aboutsummaryrefslogtreecommitdiff
path: root/drivers/video/av8100/av8100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/av8100/av8100.c')
-rw-r--r--drivers/video/av8100/av8100.c4476
1 files changed, 2471 insertions, 2005 deletions
diff --git a/drivers/video/av8100/av8100.c b/drivers/video/av8100/av8100.c
index 631654ab02a..ccabeb8caa8 100644
--- a/drivers/video/av8100/av8100.c
+++ b/drivers/video/av8100/av8100.c
@@ -1,2432 +1,2898 @@
/*
- * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) ST-Ericsson AB 2010
*
- * License terms:
+ * AV8100 driver
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
+ * Author: Per Persson <per.xb.persson@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms: GNU General Public License (GPL), version 2.
*/
-#include <linux/types.h>
+
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
+#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
-#include <linux/poll.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
#include <linux/i2c.h>
-#include <linux/workqueue.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
#include <linux/kthread.h>
+#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <asm/irq.h>
-#include <asm/ioctl.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/types.h>
-#include <mach/hardware.h>
-#include <mach/debug.h>
-#include <linux/gpio.h>
-#include <mach/mcde.h>
-#include <mach/dsi.h>
-
-#include <mach/av8100_p.h>
-#include <mach/av8100_fw.h>
-
-#define DRIVER_NAME (av8100_driver.driver.name)
+#include <linux/timer.h>
+#include <linux/mutex.h>
+
+#include "av8100_regs.h"
+#include <video/av8100.h>
+#include <video/hdmi.h>
+#include "av8100_fw.h"
+
+#define AV8100_INT_EVENT 0x1
+#define AV8100_TIMER_INT_EVENT 0x2
+
+#define AV8100_TIMER_INTERRUPT_POLLING_TIME 250
+
+#define AV8100_DRIVER_MINOR_NUMBER 240
+#define GPIO_AV8100_RSTN 196
+#define AV8100_MASTER_CLOCK_TIMING 0x3
+#define AV8100_ON_TIME 1
+#define AV8100_OFF_TIME 0
+#define AV8100_COMMAND_OFFSET 0x10
+#define AV8100_COMMAND_MAX_LENGTH 0x81
+
+#define AV8100_TE_LINE_NB_14 14
+#define AV8100_TE_LINE_NB_17 17
+#define AV8100_TE_LINE_NB_18 18
+#define AV8100_TE_LINE_NB_21 21
+#define AV8100_TE_LINE_NB_22 22
+#define AV8100_TE_LINE_NB_30 30
+#define AV8100_TE_LINE_NB_38 38
+#define AV8100_TE_LINE_NB_40 40
+#define AV8100_UI_X4_DEFAULT 6
+
+#define HDMI_REQUEST_FOR_REVOCATION_LIST_INPUT 2
+#define HDMI_CEC_MESSAGE_WRITE_BUFFER_SIZE 16
+#define HDMI_HDCP_SEND_KEY_SIZE 7
+#define HDMI_INFOFRAME_DATA_SIZE 28
+#define HDMI_CEC_MESSAGE_READBACK_MAXSIZE 16
+#define HDMI_FUSE_AES_KEY_SIZE 16
+
+#define REG_16_8_LSB(p) (u8)(p & 0xFF)
+#define REG_16_8_MSB(p) (u8)((p & 0xFF00)>>8)
+#define REG_32_8_MSB(p) (u8)((p & 0xFF000000)>>24)
+#define REG_32_8_MMSB(p) (u8)((p & 0x00FF0000)>>16)
+#define REG_32_8_MLSB(p) (u8)((p & 0x0000FF00)>>8)
+#define REG_32_8_LSB(p) (u8)(p & 0x000000FF)
+#define REG_10_8_MSB(p) (u8)((p & 0x300)>>8)
+
+
+struct av8100_config_t {
+ struct i2c_client *client;
+ struct i2c_device_id *id;
+ struct av8100_video_input_format_cmd hdmi_video_input_cmd;
+ struct av8100_audio_input_format_cmd hdmi_audio_input_cmd;
+ struct av8100_video_output_format_cmd hdmi_video_output_cmd;
+ struct av8100_video_scaling_format_cmd hdmi_video_scaling_cmd;
+ struct av8100_color_space_conversion_format_cmd
+ hdmi_color_space_conversion_cmd;
+ struct av8100_cec_message_write_format_cmd
+ hdmi_cec_message_write_cmd;
+ struct av8100_cec_message_read_back_format_cmd
+ hdmi_cec_message_read_back_cmd;
+ struct av8100_denc_format_cmd hdmi_denc_cmd;
+ struct av8100_hdmi_cmd hdmi_cmd;
+ struct av8100_hdcp_send_key_format_cmd hdmi_hdcp_send_key_cmd;
+ struct av8100_hdcp_management_format_cmd
+ hdmi_hdcp_management_format_cmd;
+ struct av8100_infoframes_format_cmd hdmi_infoframes_cmd;
+ struct av8100_edid_section_readback_format_cmd
+ hdmi_edid_section_readback_cmd;
+ struct av8100_pattern_generator_format_cmd hdmi_pattern_generator_cmd;
+ struct av8100_fuse_aes_key_format_cmd hdmi_fuse_aes_key_cmd;
+};
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("JAYARAMI REDDY");
-MODULE_DESCRIPTION("AV8100 driver for U8500");
+/**
+ * struct av8100_cea - CEA(consumer electronic access) standard structure
+ * @cea_id:
+ * @cea_nb:
+ * @vtotale:
+ **/
-extern void u8500_mcde_tasklet_4(unsigned long);
+struct av8100_cea {
+ char cea_id[40];
+ int cea_nb;
+ int vtotale;
+ int vactive;
+ int vsbp;
+ int vslen;
+ int vsfp;
+ char vpol[5];
+ int htotale;
+ int hactive;
+ int hbp;
+ int hslen;
+ int hfp;
+ int frequence;
+ char hpol[5];
+ int reg_line_duration;
+ int blkoel_duration;
+ int uix4;
+ int pll_mult;
+ int pll_div;
+};
-/*#define AV8100_USE_KERNEL_THREAD*/
+enum av8100_command_size {
+ AV8100_COMMAND_VIDEO_INPUT_FORMAT_SIZE = 0x17,
+ AV8100_COMMAND_AUDIO_INPUT_FORMAT_SIZE = 0x8,
+ AV8100_COMMAND_VIDEO_OUTPUT_FORMAT_SIZE = 0x1E,
+ AV8100_COMMAND_VIDEO_SCALING_FORMAT_SIZE = 0x11,
+ AV8100_COMMAND_COLORSPACECONVERSION_SIZE = 0x1D,
+ AV8100_COMMAND_CEC_MESSAGE_WRITE_SIZE = 0x12,
+ AV8100_COMMAND_CEC_MESSAGE_READ_BACK_SIZE = 0x1,
+ AV8100_COMMAND_DENC_SIZE = 0x6,
+ AV8100_COMMAND_HDMI_SIZE = 0x4,
+ AV8100_COMMAND_HDCP_SENDKEY_SIZE = 0xA,
+ AV8100_COMMAND_HDCP_MANAGEMENT_SIZE = 0x4,
+ AV8100_COMMAND_INFOFRAMES_SIZE = 0x21,
+ AV8100_COMMAND_EDID_SECTION_READBACK_SIZE = 0x3,
+ AV8100_COMMAND_PATTERNGENERATOR_SIZE = 0x4,
+ AV8100_COMMAND_FUSE_AES_KEY_SIZE = 0x12,
+};
-#if !defined CONFIG_FB_U8500_MCDE_CHANNELC0_DISPLAY_HDMI && \
- !defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI && \
- !defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
-#define TEST_PATTERN_TEST
-#endif
+DEFINE_MUTEX(av8100_hw_mutex);
+#define LOCK_AV8100_HW mutex_lock(&av8100_hw_mutex)
+#define UNLOCK_AV8100_HW mutex_unlock(&av8100_hw_mutex)
-#define HDMI_LOGGING
-#define CONFIG_MCDE_COLOURED_PRINTS
-
-#define PRNK_COL_BLACK 30
-#define PRNK_COL_RED 31
-#define PRNK_COL_GREEN 32
-#define PRNK_COL_YELLOW 33
-#define PRNK_COL_BLUE 34
-#define PRNK_COL_MAGENTA 35
-#define PRNK_COL_CYAN 36
-#define PRNK_COL_WHITE 37
-
-#ifdef CONFIG_MCDE_COLOURED_PRINTS
-#define PRNK_COL(_col) printk(KERN_ERR "%c[0;%d;40m\n", 0x1b, _col)
-#else /* CONFIG_MCDE_COLOURED_PRINTS */
-#define PRNK_COL(_col)
-#endif /* CONFIG_MCDE_COLOURED_PRINTS */
-
-#ifdef HDMI_LOGGING
-#define HDMI_TRACE do {\
- PRNK_COL(PRNK_COL_YELLOW);\
- printk(KERN_DEBUG "HDMI send cmd %s\n", __func__);\
- PRNK_COL(PRNK_COL_WHITE);\
-} while (0)
-#else
-#define HDMI_TRACE
-#endif
+#define AV8100_DEBUG_EXTRA
+#define AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS
static int av8100_open(struct inode *inode, struct file *filp);
static int av8100_release(struct inode *inode, struct file *filp);
-static int av8100_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-static void av8100_configure_hdmi(struct i2c_client *i2c);
-static void av8100_configure_denc(struct av8100_data *av8100DataTemp);
-static irqreturn_t av8100_intr_handler(int irq, void *p);
-
-static int av8100_write_multi_byte(struct i2c_client *client, unsigned char regOffset,unsigned char *buf,unsigned char nbytes);
-static int av8100_write_single_byte(struct i2c_client *client, unsigned char reg,unsigned char data);
-#if 0
-static int av8100_read_multi_byte(struct i2c_client *client,unsigned char reg,unsigned char *buf, unsigned char nbytes);
-#endif
-static int av8100_read_single_byte(struct i2c_client *client,unsigned char reg, unsigned char* val);
-static void av8100_hdmi_on(struct av8100_data *av8100DataTemp);
-static void av8100_hdmi_off(struct av8100_data *av8100DataTemp);
-static int configure_av8100_video_input(char* buffer_temp);
-static int configure_av8100_audio_input(char* buffer_temp);
-static int configure_av8100_video_output(char* buffer_temp);
-static int configure_av8100_video_scaling(char* buffer_temp);
-static int configure_av8100_colorspace_conversion(char* buffer_temp);
-static int configure_av8100_cec_message_write(char* buffer_temp);
-static int configure_av8100_cec_message_read(char* buffer_temp);
-static int configure_av8100_denc(char* buffer_temp);
-static int configure_av8100_hdmi(char* buffer_temp);
-static int configure_av8100_hdcp_senkey(char* buffer_temp);
-static int configure_av8100_hdcp_management(char* buffer_temp);
-static int configure_av8100_infoframe(char* buffer_temp);
-static int configure_av8100_pattern_generator(char* buffer_temp);
-#if 0
-static int read_edid_info(struct i2c_client *i2c, char* buff);
-#endif
-static int av8100_send_command (struct i2c_client *i2cClient, char command_type, enum interface if_type);
-static int av8100_powerdown(void);
-static int av8100_powerup(struct i2c_client *i2c, const struct i2c_device_id *id);
-static int av8100_enable_interrupt(struct i2c_client *i2c);
-static int av8100_probe(struct i2c_client *i2cClient,const struct i2c_device_id *id);
-static int __exit av8100_remove(struct i2c_client *i2cClient);
-static int av8100_download_firmware(struct i2c_client *i2c, char regoffset, char* fw_buff, int numOfBytes, enum interface if_type);
-static unsigned short av8100_get_ui_x4(av8100_output_CEA_VESA output_video_format);
-static unsigned short av8100_get_te_line_nb(av8100_output_CEA_VESA output_video_format);
-static void av8100_init_config_params(void);
-static void av8100_config_output_dep_params(void);
-#if defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI ||\
- defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
-static mcde_video_mode av8100_get_mcde_video_mode(av8100_output_CEA_VESA format);
+static int av8100_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static int __devinit av8100_probe(struct i2c_client *i2cClient,
+ const struct i2c_device_id *id);
+static int __devexit av8100_remove(struct i2c_client *i2cClient);
+
+static struct av8100_config_t *av8100_config;
+static struct av8100_status g_av8100_status = {0};
+#ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS
+static struct timer_list av8100_timer;
#endif
-static void av8100_set_state(av8100_operating_mode state);
-static av8100_operating_mode av8100_get_state(void);
-
-#define uint8 unsigned char
-
-/** global data */
-unsigned int g_av8100_cmd_length=0;
-unsigned int g_dcs_data_count_index = 0;
-unsigned int g_dcs_data_count_last = 0;
-struct av8100_data *av8100Data;
-av8100_operating_mode g_av8100_state = AV8100_OPMODE_SHUTDOWN;
-
-av8100_video_input_format_cmd hdmi_video_input_cmd;
-av8100_video_output_format_cmd hdmi_video_output_cmd;
-av8100_hdmi_cmd hdmi_cmd;
-av8100_pattern_generator_cmd hdmi_pattern_generator_cmd;
-av8100_audio_input_format_cmd hdmi_audio_input_cmd;
-av8100_color_space_conversion_cmd hdmi_color_conversion_cmd;
-av8100_denc_cmd hdmi_denc_cmd;
-
-wait_queue_head_t av8100_event;
-bool av8100_flag = 0x0;
-
-int length = 0x0;
-extern unsigned int isReady;
-#define DSI_MAX_DATA_WRITE 15
-
-av8100_cea av8100_all_cea[29] ={
-/* cea id cea_nr vtot vact vsbpp vslen vsfp vpol htot hact hbp hslen hfp freq hpol rld,bd,uix4,pm,pd */
-{ "0 CUSTOM " , 0 ,0 , 0 ,0 , 0 , 0 , "-" , 800 ,640 , 16 , 96 , 10, 25200000 ,"-",0,0,0,0,0},//Settings to be define
-{ "1 CEA 1 VESA 4 640x480p @ 60 Hz " , 1 ,525 , 480 ,33 , 2 , 10 , "-" , 800 ,640 , 49 , 290 , 146, 25200000 ,"-",2438,1270,6,32,1},//RGB888
-{ "2 CEA 2 - 3 720x480p @ 60 Hz 4:3 " , 2 ,525 , 480 ,30 , 6 , 9 , "-" , 858 ,720 , 34 , 130 , 128, 27027000 ,"-",1828,0x3C0,8,24,1},//RGB565
-{ "3 CEA 4 1280x720p @ 60 Hz " , 4 ,750 , 720 ,20 , 5 , 5 , "+" , 1650 ,1280 , 114 , 39 , 228, 74250000 ,"+",1706,164,6,32,1},//RGB565
-{ "4 CEA 5 1920x1080i @ 60 Hz " , 5 ,1125 , 540 ,20 , 5 , 0 , "+" , 2200 ,1920 , 88 , 44 , 10, 74250000 ,"+",0,0,0,0,0},//Settings to be define
-{ "5 CEA 6-7 480i (NTSC) " , 6 ,525 , 240 ,44 , 5 , 0 , "-" , 1716 ,1440 , 12 , 64 , 10, 27000000 ,"-",0,0,0,0,0},//Settings to be define
-{ "6 CEA 14-15 480p @ 60 Hz " , 14 ,525 , 480 ,44 , 5 , 0 , "-" , 858 ,720 , 12 , 64 , 10, 27000000 ,"-",0,0,0,0,0},//Settings to be define
-{ "7 CEA 16 1920x1080p @ 60 Hz " , 16 ,1125 , 1080 ,36 , 5 , 0 , "+" , 1980 ,1280 , 440 , 40 , 10, 74250000 ,"+",0,0,0,0,0},//Settings to be define
-{ "8 CEA 17-18 720x576p @ 50 Hz " , 17 ,625 , 576 ,44 , 5 , 0 , "-" , 864 ,720 , 12 , 64 , 10, 27000000 ,"-",0,0,0,0,0},//Settings to be define
-{ "9 CEA 19 1280x720p @ 50 Hz " , 19 ,750 , 720 ,25 , 5 , 0 , "+" , 1980 ,1280 , 440 , 40 , 10, 74250000 ,"+",0,0,0,0,0},//Settings to be define
-{ "10 CEA 20 1920 x 1080i @ 50 Hz " , 20 ,1125 , 540 ,20 , 5 , 0 , "+" , 2640 ,1920 , 528 , 44 , 10, 74250000 ,"+",0,0,0,0,0},//Settings to be define
-{ "11 CEA 21-22 576i (PAL) " , 21 ,625 , 288 ,44 , 5 , 0 , "-" , 1728 ,1440 , 12 , 64 , 10, 27000000 ,"-",0,0,0,0,0},//Settings to be define
-{ "12 CEA 29/30 576p " , 29 ,625 , 576 ,44 , 5 , 0 , "-" , 864 ,720 , 12 , 64 , 10, 27000000 ,"-",0,0,0,0,0},//Settings to be define
-{ "13 CEA 31 1080p 50Hz " , 31 ,1125 , 1080 ,44 , 5 , 0 , "-" , 2750 ,1920 , 12 , 64 , 10, 27000000 ,"-",0,0,0,0,0},//Settings to be define
-{ "14 CEA 32 1920x1080p @ 24 Hz " , 32 ,1125 , 1080 ,36 , 5 , 4 , "+" , 2750 ,1920 , 660 , 44 , 153, 74250000 ,"+",2844,0x530,6,32,1},//RGB565
-{ "15 CEA 33 1920x1080p @ 25 Hz " , 33 ,1125 , 1080 ,36 , 5 , 4 , "+" , 2640 ,1920 , 528 , 44 , 10, 74250000 ,"+",0,0,0,0,0},//Settings to be define
-{ "16 CEA 34 1920x1080p @ 30Hz " , 34 ,1125 , 1080 ,36 , 5 , 4 , "+" , 2200 ,1920 , 91 , 44 , 153, 74250000 ,"+",2275,0xAB,6,32,1},//RGB565
-{ "17 CEA 60 1280x720p @ 24 Hz " , 60 ,750 , 720 ,20 , 5 , 5 , "+" , 3300 ,1280 , 284 , 50 , 2276, 29700000 ,"+",4266,0xAD0,5,32,1},//RGB565
-{ "18 CEA 61 1280x720p @ 25 Hz " , 61 ,750 , 720 ,20 , 5 , 5 , "+" , 3960 ,1280 , 228 , 39 , 2503 ,30937500 ,"+",4096,0x500,5,32,1},//RGB565
-{ "19 CEA 62 1280x720p @ 30 Hz " , 62 ,750 , 720 ,20 , 5 , 5 , "+" , 3300 ,1280 , 228 , 39 , 1820, 37125000 ,"+",3413,0x770,5,32,1},//RGB565
-{ "20 VESA 9 800x600 @ 60 Hz " , 109 ,628 , 600 ,28 , 4 , 0 , "+" , 1056 ,800 , 40 , 128 , 10, 40000000 ,"+",0,0,0,0,0},//Settings to be define
-{ "21 VESA 14 848x480 @ 60 Hz " , 114 ,500 , 480 ,20 , 5 , 0 , "+" , 1056 ,848 , 24 , 80 , 10, 31500000 ,"-",0,0,0,0,0},//Settings to be define
-{ "22 VESA 16 1024x768 @ 60 Hz " , 116 ,806 , 768 ,38 , 6 , 0 , "-" , 1344 ,1024 , 24 , 135 , 10, 65000000 ,"-",0,0,0,0,0},//Settings to be define
-{ "23 VESA 22 1280x768 @ 60 Hz " , 122 ,802 , 768 ,34 , 4 , 0 , "+" , 1688 ,1280 , 48 , 160 , 10, 81250000 ,"-",0,0,0,0,0},//Settings to be define
-{ "24 VESA 23 1280x768 @ 60 Hz " , 123 ,798 , 768 ,30 , 7 , 0 , "+" , 1664 ,1280 , 64 , 128 , 10, 79500000 ,"-",0,0,0,0,0},//Settings to be define
-{ "25 VESA 27 1280x800 @ 60 Hz " , 127 ,823 , 800 ,23 , 6 , 0 , "+" , 1440 ,1280 , 48 , 32 , 10, 71000000 ,"+",0,0,0,0,0},//Settings to be define
-{ "26 VESA 28 1280x800 @ 60 Hz " , 128 ,831 , 800 ,31 , 6 , 0 , "+" , 1680 ,1280 , 72 , 128 , 10, 83500000 ,"-",0,0,0,0,0},//Settings to be define
-{ "27 VESA 39 1360x768 @ 60 Hz " , 139 ,790 , 768 ,22 , 5 , 0 , "-" , 1520 ,1360 , 48 , 32 , 10, 72000000 ,"+",0,0,0,0,0},//Settings to be define
-{ "28 VESA 81 1360x768 @ 60 Hz " , 181 ,798 , 768 ,30 , 5 , 0 , "+" , 1776 ,1360 , 72 , 136 , 10, 84750000 ,"-",0,0,0,0,0}//Settings to be define
-};
+static wait_queue_head_t av8100_event;
+static int av8100_flag = 0x0;
-/** av8100 file operations */
-static struct file_operations av8100_fops = {
+static const struct file_operations av8100_fops = {
.owner = THIS_MODULE,
.open = av8100_open,
.release = av8100_release,
.ioctl = av8100_ioctl
};
-/** av8100 misc device structure */
-static struct miscdevice av8100_miscdev =
-{
+static struct miscdevice av8100_miscdev = {
AV8100_DRIVER_MINOR_NUMBER,
"av8100",
&av8100_fops
};
-/**
- * av8100_write_multi_byte() - Write a multiple bytes to av8100 chip(av8100) through i2c interface.
- * @client: i2c client structure
- * @buf: buffer to be written
- * @nbytes: nunmber of bytes to be written
- *
- * This funtion uses smbus block write API's to write n number of bytes to the av8100
- **/
-static int av8100_write_multi_byte(struct i2c_client *client, uint8 regOffset,
- uint8 *buf,uint8 nbytes)
-{
- int ret = AV8100_OK;
- //u8 temp;
-
- ret = i2c_smbus_write_i2c_block_data(client, regOffset,nbytes, buf);
- if (ret < 0) {
- printk("i2c smbus write multi byte error\n");
- return ret;
- }
- length += nbytes;
- //printk("length:%d\n", length);
-#if 0
- if(nbytes < 40)
- {
- for (temp = 0; temp < nbytes; temp++)
- printk("value:%0x\n", buf[temp]);
- printk("FW size:%d\n", length);
- }
-#endif
+struct av8100_cea av8100_all_cea[29] = {
+/* cea id
+ * cea_nr vtot vact vsbpp vslen
+ * vsfp vpol htot hact hbp hslen hfp freq
+ * hpol rld bd uix4 pm pd */
+{ "0 CUSTOM ",
+ 0, 0, 0, 0, 0,
+ 0, "-", 800, 640, 16, 96, 10, 25200000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be defined*/
+{ "1 CEA 1 VESA 4 640x480p @ 60 Hz ",
+ 1, 525, 480, 33, 2,
+ 10, "-", 800, 640, 49, 290, 146, 25200000,
+ "-", 2438, 1270, 6, 32, 1},/*RGB888*/
+{ "2 CEA 2 - 3 720x480p @ 60 Hz 4:3 ",
+ 2, 525, 480, 30, 6,
+ 9, "-", 858, 720, 34, 130, 128, 27027000,
+ "-", 1828, 0x3C0, 8, 24, 1},/*RGB565*/
+{ "3 CEA 4 1280x720p @ 60 Hz ",
+ 4, 750, 720, 20, 5,
+ 5, "+", 1650, 1280, 114, 39, 228, 74250000,
+ "+", 1706, 164, 6, 32, 1},/*RGB565*/
+{ "4 CEA 5 1920x1080i @ 60 Hz ",
+ 5, 1125, 540, 20, 5,
+ 0, "+", 2200, 1920, 88, 44, 10, 74250000,
+ "+", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "5 CEA 6-7 480i (NTSC) ",
+ 6, 525, 240, 44, 5,
+ 0, "-", 858, 720, 12, 64, 10, 27000000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "6 CEA 14-15 480p @ 60 Hz ",
+ 14, 525, 480, 44, 5,
+ 0, "-", 858, 720, 12, 64, 10, 27000000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "7 CEA 16 1920x1080p @ 60 Hz ",
+ 16, 1125, 1080, 36, 5,
+ 0, "+", 1980, 1280, 440, 40, 10, 74250000,
+ "+", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "8 CEA 17-18 720x576p @ 50 Hz ",
+ 17, 625, 576, 44, 5,
+ 0, "-", 864, 720, 12, 64, 10, 27000000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "9 CEA 19 1280x720p @ 50 Hz ",
+ 19, 750, 720, 25, 5,
+ 0, "+", 1980, 1280, 440, 40, 10, 74250000,
+ "+", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "10 CEA 20 1920 x 1080i @ 50 Hz ",
+ 20, 1125, 540, 20, 5,
+ 0, "+", 2640, 1920, 528, 44, 10, 74250000,
+ "+", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "11 CEA 21-22 576i (PAL) ",
+ 21, 625, 288, 44, 5,
+ 0, "-", 864, 720, 12, 64, 10, 27000000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "12 CEA 29/30 576p ",
+ 29, 625, 576, 44, 5,
+ 0, "-", 864, 720, 12, 64, 10, 27000000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "13 CEA 31 1080p 50Hz ",
+ 31, 1125, 1080, 44, 5,
+ 0, "-", 2750, 1920, 12, 64, 10, 27000000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "14 CEA 32 1920x1080p @ 24 Hz ",
+ 32, 1125, 1080, 36, 5,
+ 4, "+", 2750, 1920, 660, 44, 153, 74250000,
+ "+", 2844, 0x530, 6, 32, 1},/*RGB565*/
+{ "15 CEA 33 1920x1080p @ 25 Hz ",
+ 33, 1125, 1080, 36, 5,
+ 4, "+", 2640, 1920, 528, 44, 10, 74250000,
+ "+", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "16 CEA 34 1920x1080p @ 30Hz ",
+ 34, 1125, 1080, 36, 5,
+ 4, "+", 2200, 1920, 91, 44, 153, 74250000,
+ "+", 2275, 0xAB, 6, 32, 1},/*RGB565*/
+{ "17 CEA 60 1280x720p @ 24 Hz ",
+ 60, 750, 720, 20, 5,
+ 5, "+", 3300, 1280, 284, 50, 2276, 29700000,
+ "+", 4266, 0xAD0, 5, 32, 1},/*RGB565*/
+{ "18 CEA 61 1280x720p @ 25 Hz ",
+ 61, 750, 720, 20, 5,
+ 5, "+", 3960, 1280, 228, 39, 2503, 30937500,
+ "+", 4096, 0x500, 5, 32, 1},/*RGB565*/
+{ "19 CEA 62 1280x720p @ 30 Hz ",
+ 62, 750, 720, 20, 5,
+ 5, "+", 3300, 1280, 228, 39, 1820, 37125000,
+ "+", 3413, 0x770, 5, 32, 1},/*RGB565*/
+{ "20 VESA 9 800x600 @ 60 Hz ",
+ 109, 628, 600, 28, 4,
+ 0, "+", 1056, 800, 40, 128, 10, 40000000,
+ "+", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "21 VESA 14 848x480 @ 60 Hz ",
+ 114, 500, 480, 20, 5,
+ 0, "+", 1056, 848, 24, 80, 10, 31500000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "22 VESA 16 1024x768 @ 60 Hz ",
+ 116, 806, 768, 38, 6,
+ 0, "-", 1344, 1024, 24, 135, 10, 65000000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "23 VESA 22 1280x768 @ 60 Hz ",
+ 122, 802, 768, 34, 4,
+ 0, "+", 1688, 1280, 48, 160, 10, 81250000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "24 VESA 23 1280x768 @ 60 Hz ",
+ 123, 798, 768, 30, 7,
+ 0, "+", 1664, 1280, 64, 128, 10, 79500000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "25 VESA 27 1280x800 @ 60 Hz ",
+ 127, 823, 800, 23, 6,
+ 0, "+", 1440, 1280, 48, 32, 10, 71000000,
+ "+", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "26 VESA 28 1280x800 @ 60 Hz ",
+ 128, 831, 800, 31, 6,
+ 0, "+", 1680, 1280, 72, 128, 10, 83500000,
+ "-", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "27 VESA 39 1360x768 @ 60 Hz ",
+ 139, 790, 768, 22, 5,
+ 0, "-", 1520, 1360, 48, 32, 10, 72000000,
+ "+", 0, 0, 0, 0, 0},/*Settings to be define*/
+{ "28 VESA 81 1360x768 @ 60 Hz ",
+ 181, 798, 768, 30, 5,
+ 0, "+", 1776, 1360, 72, 136, 10, 84750000,
+ "-", 0, 0, 0, 0, 0} /*Settings to be define*/
+};
- /* FIXME- workaround,i2c_smbus_write_i2c_block_data doesn't work on this platform!*/
-#if 0
- for(temp=0;temp<nbytes-1;temp++) {
- ret = i2c_smbus_write_byte_data(client,0xF/*(regOffset)*/,buf[temp]);
- if (ret < 0) {
- printk("i2c smbus write byte error\n");
- return ret;
- }else
- printk("av8100_write_multi_byte ret:%x\n", ret);
- }
-#endif
- return ret;
-}
-/**
- * av8100_write_single_byte() - Write a single byte to av8100 chip(av8100) through i2c interface.
- * @client: i2c client structure
- * @reg: register offset
- * @data: data byte to be written
- *
- * This funtion uses smbus byte write API to write a single byte to av8100
- **/
-static int av8100_write_single_byte(struct i2c_client *client, uint8 reg,
- uint8 data)
-{
- int ret = AV8100_OK;
+static const struct i2c_device_id av8100_id[] = {
+ { "av8100", 0 },
+ { }
+};
- //printk("av8100_write_single_byte: reg=%x,data = %x\n", reg,data);
- ret = i2c_smbus_write_byte_data(client,reg,data);
- if(ret < 0) {
- printk("i2c smbus write byte failed\n");
- return ret;
- }
- return ret;
-}
+static struct i2c_driver av8100_driver = {
+ .probe = av8100_probe,
+ .remove = av8100_remove,
+ .driver = {
+ .name = "av8100",
+ },
+ .id_table = av8100_id,
+};
-/**
- * av8100_read_multi_byte() - read multiple bytes from av8100 chip(av8100) through i2c interface
- * @client: i2c client structure
- * @reg: register offset
- * @buf: read the data in this buffer
- * @nbytes: number of bytes to read
- *
- * This funtion uses smbus read block API to read multiple bytes from the reg offset.
- **/
-#if 0
-static int av8100_read_multi_byte(struct i2c_client *client,uint8 reg,
- uint8 *buf, uint8 nbytes)
+#ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS
+static void av8100_timer_int(unsigned long value)
{
- int ret = AV8100_OK;
+ av8100_flag |= AV8100_TIMER_INT_EVENT;
+ wake_up_interruptible(&av8100_event);
- ret = i2c_smbus_read_i2c_block_data(client,reg,nbytes,buf);
- if(ret < 0){
- printk("i2c smbus read multi byte failed\n");
- return ret;
+ if (g_av8100_status.av8100_state >= AV8100_OPMODE_STANDBY) {
+ av8100_timer.expires = jiffies +
+ AV8100_TIMER_INTERRUPT_POLLING_TIME;
+ add_timer(&av8100_timer);
}
- if (ret < nbytes){
- printk("i2c smbus read multi byte failed\n");
- return -EIO;
- }
- return ret;
}
#endif
-/**
- * av8100_read_single_byte() - read single byte from av8100 chip(av8100) through i2c interface
- * @client: i2c client structure
- * @reg: register offset
- * @val: register value
- *
- * This funtion uses smbus read block API to read single byte from the reg offset.
- **/
-static int av8100_read_single_byte(struct i2c_client *client,uint8 reg, unsigned char* val)
+static int av8100_thread(void *p)
{
- int ret = AV8100_OK;
- int value = 0x0;
- value = i2c_smbus_read_byte_data(client, reg);
- if(value < 0){
- printk("i2c smbus read byte failed,read data = %x from offset: %x\n" ,value,reg);
- return ret;
- }
- //printk("read data = %x from offset: %x\n" ,value,reg);
- *val = value;
- return ret;
-}
-
-/**
- * get_dcs_data_index_params() - This API is used to get the number of times the data to be sent with the commands.
- **/
-void get_dcs_data_index_params(void)
-{
- g_dcs_data_count_index = 0;
- g_dcs_data_count_last = 0;
- g_dcs_data_count_index = g_av8100_cmd_length/DSI_MAX_DATA_WRITE;
- g_dcs_data_count_last = g_av8100_cmd_length%DSI_MAX_DATA_WRITE;
-}
+ u8 cpd = 0;
+ u8 stby = 0;
+ u8 hpds = 0;
+ u8 cpds = 0;
+ u8 mclkrng = 0;
+ int ret = 0;
+#ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS
+ u8 hpds_old = 0xf;
+ u8 cpds_old = 0xf;
+#else
+ u8 sid = 0;
+ u8 oni = 0;
+ u8 hpdi = 0;
+ u8 cpdi = 0;
+#endif
-/**
- * av8100_intr_handler() - To handle av8100 interrupts.
- * @irq: irq context
- * @av8100Data:av8100 data
- *
- * This funtion handles the av8100 interrupts. It handles the plugin and plugout(HDMI/CVBS) interrupts.
- **/
-static irqreturn_t av8100_intr_handler(int irq, void *p)
-{
+ while (1) {
+ wait_event_interruptible(av8100_event, (av8100_flag != 0));
+#ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS
+ if (av8100_flag & AV8100_TIMER_INT_EVENT) {
+ if (g_av8100_status.av8100_state >=
+ AV8100_OPMODE_STANDBY) {
+ /* STANDBY */
+ ret = av8100_register_standby_read(
+ &cpd,
+ &stby,
+ &hpds,
+ &cpds,
+ &mclkrng);
+ if (ret != 0)
+ printk(KERN_DEBUG "av8100_register_"
+ "standby_read fail\n");
+
+ /* TVout plugin change */
+ if ((cpds == 1) && (cpds != cpds_old)) {
+ cpds_old = 1;
+
+ g_av8100_status.av8100_plugin_status |=
+ AV8100_CVBS_PLUGIN;
+
+ /* TODO: notify */
+ printk(KERN_DEBUG "TVout plugin detected\n");
+ } else if ((cpds == 0) && (cpds != cpds_old)) {
+ cpds_old = 0;
+
+ g_av8100_status.av8100_plugin_status &=
+ ~AV8100_CVBS_PLUGIN;
+
+ /* TODO: notify */
+ printk(KERN_DEBUG "TVout plugout detected\n");
+ }
-#if 0
- struct av8100_data *av8100DataTemp = p;
-#endif
+ /* HDMI plugin change */
+ if ((hpds == 1) && (hpds != hpds_old)) {
+ hpds_old = 1;
-#if 0
- char val = 0x0;
- int retval = AV8100_OK;
- char val1 = 0x0;
-
- //printk("av8100_intr_handler is called\n");
- //mdelay(100);
-
- av8100_read_single_byte(av8100DataTemp->client, STANDBY_PENDING_INTERRUPT_REG, &val);
- printk("av8100_intr_handler is called, val:%x, av8100Data->client:%x\n",val, av8100DataTemp->client);
- if (start == 0/*val && HDMI_HOTPLUG_INTERRUPT*/)
- {
- printk("hdmi cable plugin interrupt\n");
- g_av8100_plugin_status = AV8100_HDMI_PLUGIN;
- av8100_set_state(AV8100_OPMODE_INIT);
- val = 0x0;//~ HDMI_HOTPLUG_INTERRUPT_MASK;
- start = 1;
-
- retval = av8100_write_single_byte(av8100DataTemp->client, STANDBY_PENDING_INTERRUPT_REG, val);
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to the av8100 STANDBY_PENDING_INTERRUPT_REG register\n");
- return -EFAULT;
- }
- retval = av8100_send_command (av8100DataTemp->client, AV8100_COMMAND_VIDEO_INPUT_FORMAT, I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_VIDEO_INPUT_FORMAT command\n");
- return -EFAULT;
- }
+ g_av8100_status.av8100_plugin_status |=
+ AV8100_HDMI_PLUGIN;
- retval = av8100_send_command (av8100DataTemp->client, AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_VIDEO_INPUT_FORMAT command\n");
- return -EFAULT;
- }
+ /* TODO: notify */
+ printk(KERN_DEBUG "HDMI plugin detected\n");
+ } else if ((hpds == 0) && (hpds != hpds_old)) {
+ hpds_old = 0;
- mcde_hdmi_display_init();
- mcde_configure_hdmi_channel();
+ g_av8100_status.av8100_plugin_status &=
+ ~AV8100_HDMI_PLUGIN;
- retval = av8100_write_single_byte(av8100DataTemp, GENERAL_INTERRUPT_MASK_REG, 0x60); /* enable TE */
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to the av8100 register\n");
- return -EFAULT;
+ /* TODO: notify */
+ printk(KERN_DEBUG "HDMI plugout detected\n");
+ }
+ }
}
-
- retval = av8100_send_command (av8100DataTemp->client, AV8100_COMMAND_HDMI, I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_VIDEO_INPUT_FORMAT command\n");
- return -EFAULT;
+#else
+ /* STANDBY_PENDING_INTERRUPT */
+ ret = av8100_register_standby_pending_interrupt_read(
+ &hpdi,
+ &cpdi,
+ &oni,
+ &sid);
+
+ if (ret)
+ printk(KERN_DEBUG "av8100_register_standby_"
+ "pending_interrupt_read failed\n");
+
+ if (hpdi | cpdi | oni) {
+ /* STANDBY */
+ ret = av8100_register_standby_read(
+ &cpd,
+ &stby,
+ &hpds,
+ &cpds,
+ &mclkrng);
+ if (ret)
+ printk(KERN_DEBUG "av8100_register_standby_"
+ "read fail\n");
}
-
- }
- else if (val && CVBS_PLUG_INTERRUPT) {
- g_av8100_plugin_status = AV8100_CVBS_PLUGIN;
- av8100_set_state(AV8100_OPMODE_INIT);
- val = ~CVBS_PLUG_INTERRUPT_MASK;
- av8100_write_single_byte(av8100DataTemp->client, STANDBY_PENDING_INTERRUPT_REG, val);
- }
- else {
- g_av8100_plugin_status = AV8100_PLUGIN_NONE;
- }
-
- retval = av8100_read_single_byte(av8100DataTemp->client, 0x0/*STANDBY_PENDING_INTERRUPT_REG*/, &val);
- if(retval != AV8100_OK)
- {
- printk("Failed to read the STANDBY_PENDING_INTERRUPT_REG\n");
- return -EFAULT;
- }
-
- printk("av8100_read_single_byte(av8100DataTemp->client, GENERAL_INTERRUPT_REG, &val1)\n");
- retval = av8100_read_single_byte(av8100DataTemp->client, GENERAL_INTERRUPT_REG, &val1);
- if(retval != AV8100_OK)
- {
- printk("Failed to read the GENERAL_INTERRUPT_REG\n");
- return -EFAULT;
- }
-
- if(val1 && TE_INTERRUPT_MASK)
- {
- //printk("Received the TE interrupt\n");
- retval = av8100_write_single_byte(av8100DataTemp->client, GENERAL_INTERRUPT_REG, TE_INTERRUPT_MASK);
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to the av8100 GENERAL_INTERRUPT_REG register\n");
- return -EFAULT;
+ if (cpdi) {
+ /* TVout plugin change */
+ if (cpds)
+ g_av8100_status.av8100_plugin_status |=
+ AV8100_CVBS_PLUGIN;
+ else
+ g_av8100_status.av8100_plugin_status &=
+ ~AV8100_CVBS_PLUGIN;
+
+ /* TODO: notify */
+ printk(KERN_DEBUG "TVout plugin: %d\n", (
+ g_av8100_status.av8100_plugin_status &
+ AV8100_CVBS_PLUGIN) == AV8100_CVBS_PLUGIN);
+ } else if (hpdi) {
+ /* HDMI plugin change */
+ if (hpds)
+ g_av8100_status.av8100_plugin_status |=
+ AV8100_HDMI_PLUGIN;
+ else
+ g_av8100_status.av8100_plugin_status &=
+ ~AV8100_HDMI_PLUGIN;
+
+ /* TODO: notify */
+ printk(KERN_DEBUG "HDMI plugin: %d\n", (
+ g_av8100_status.av8100_plugin_status &
+ AV8100_HDMI_PLUGIN) == AV8100_HDMI_PLUGIN);
}
- }
- if(val1 && UNDER_OVER_FLOW_INTERRUPT_MASK)
- {
- //printk("Received the underflow/overflow interrupt\n");
- retval = av8100_write_single_byte(av8100DataTemp->client, GENERAL_INTERRUPT_REG, UNDER_OVER_FLOW_INTERRUPT_MASK);
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to the av8100 GENERAL_INTERRUPT_REG register\n");
- return -EFAULT;
+ if (hpdi | cpdi | oni) {
+ /* Clear pending interrupts */
+ ret = av8100_register_standby_pending_interrupt_write(
+ hpdi,
+ cpdi,
+ oni);
+ if (ret)
+ printk(KERN_DEBUG "av8100_register_standby_"
+ "read fail\n");
}
- }
#endif
+ av8100_flag = 0;
+ }
-#ifdef AV8100_USE_KERNEL_THREAD
- av8100_flag = 1;
+ return ret;
+}
+
+static irqreturn_t av8100_intr_handler(int irq, void *p)
+{
+ av8100_flag |= AV8100_INT_EVENT;
wake_up_interruptible(&av8100_event);
-#else
- u8500_mcde_tasklet_4(0);
-#endif
return IRQ_HANDLED;
}
-
-/**
- * av8100_configure_hdmi() - To configure the av8100 chip for hdmi.
- * @av8100Data:av8100 data
- *
- * This funtion configures the video input, video output, test pattern and hdmi on commands.
- **/
-static void av8100_configure_hdmi(struct i2c_client *i2c)
+static u16 av8100_get_te_line_nb(
+ enum av8100_output_CEA_VESA output_video_format)
{
- char val = 0x0;
- int retval = AV8100_OK;
+ u16 retval;
-#if 0
- av8100_read_single_byte(i2c, STANDBY_PENDING_INTERRUPT_REG, &val);
- printk("av8100_intr_handler is called, val:%x, av8100Data->client:%x\n",val, i2c);
-#endif
+ switch (output_video_format) {
+ case AV8100_CEA1_640X480P_59_94HZ:
+ case AV8100_CEA2_3_720X480P_59_94HZ:
+ retval = AV8100_TE_LINE_NB_30;
+ break;
- retval = av8100_write_single_byte(i2c, STANDBY_PENDING_INTERRUPT_REG, val);
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to the av8100 STANDBY_PENDING_INTERRUPT_REG register\n");
- return;
- }
+ case AV8100_CEA5_1920X1080I_60HZ:
+ case AV8100_CEA6_7_NTSC_60HZ:
+ case AV8100_CEA20_1920X1080I_50HZ:
+ retval = AV8100_TE_LINE_NB_18;
+ break;
-#ifndef TEST_PATTERN_TEST
- retval = av8100_send_command (i2c, AV8100_COMMAND_VIDEO_INPUT_FORMAT,/*DSI_INTERFACE*/I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_VIDEO_INPUT_FORMAT command\n");
- return;
- }
+ case AV8100_CEA4_1280X720P_60HZ:
+ retval = AV8100_TE_LINE_NB_21;
+ break;
-#ifdef CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- retval = av8100_send_command (i2c, AV8100_COMMAND_COLORSPACECONVERSION, I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_COLORSPACECONVERSION command\n");
- return;
- }
-#endif /* CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV */
+ case AV8100_CEA17_18_720X576P_50HZ:
+ retval = AV8100_TE_LINE_NB_40;
+ break;
-#else /* TEST_PATTERN_TEST */
-#ifndef CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
+ case AV8100_CEA19_1280X720P_50HZ:
+ retval = AV8100_TE_LINE_NB_22;
+ break;
- retval = av8100_send_command (i2c, AV8100_COMMAND_PATTERNGENERATOR, /*DSI_INTERFACE*/I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_PATTERNGENERATOR command\n");
- return;
- }
-#endif /* CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV */
-#endif
- retval = av8100_send_command (i2c, AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_VIDEO_OUTPUT_FORMAT command\n");
- return;
- }
-#ifndef TEST_PATTERN_TEST
-#ifdef CONFIG_FB_U8500_MCDE_CHANNELC0_DISPLAY_HDMI
- mcde_hdmi_display_init_video_mode();
+ case AV8100_CEA21_22_576I_PAL_50HZ:
+ /* Different values below come from LLD,
+ * TODO: check if this is really needed
+ * if not merge with AV8100_CEA6_7_NTSC_60HZ case
+ */
+#ifdef CONFIG_AV8100_SDTV
+ retval = AV8100_TE_LINE_NB_18;
+#else
+ retval = AV8100_TE_LINE_NB_17;
#endif
- retval = av8100_send_command (i2c, AV8100_COMMAND_AUDIO_INPUT_FORMAT, I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_AUDIO_INPUT_FORMAT command\n");
- return;
+ break;
+
+ case AV8100_CEA32_1920X1080P_24HZ:
+ case AV8100_CEA33_1920X1080P_25HZ:
+ case AV8100_CEA34_1920X1080P_30HZ:
+ retval = AV8100_TE_LINE_NB_38;
+ break;
+
+ case AV8100_CEA60_1280X720P_24HZ:
+ case AV8100_CEA62_1280X720P_30HZ:
+ retval = AV8100_TE_LINE_NB_21;
+ break;
+
+ case AV8100_CEA14_15_480p_60HZ:
+ case AV8100_VESA14_848X480P_60HZ:
+ case AV8100_CEA61_1280X720P_25HZ:
+ case AV8100_CEA16_1920X1080P_60HZ:
+ case AV8100_CEA31_1920x1080P_50Hz:
+ case AV8100_CEA29_30_576P_50HZ:
+ case AV8100_VESA9_800X600P_60_32HZ:
+ case AV8100_VESA16_1024X768P_60HZ:
+ case AV8100_VESA22_1280X768P_59_99HZ:
+ case AV8100_VESA23_1280X768P_59_87HZ:
+ case AV8100_VESA27_1280X800P_59_91HZ:
+ case AV8100_VESA28_1280X800P_59_81HZ:
+ case AV8100_VESA39_1360X768P_60_02HZ:
+ case AV8100_VESA81_1366X768P_59_79HZ:
+ default:
+ /* TODO */
+ retval = AV8100_TE_LINE_NB_14;
+ break;
}
-#endif /* TEST_PATTERN_TEST */
- av8100_configure_denc(av8100Data);
- return;
+
+ return retval;
}
-static void av8100_configure_denc(struct av8100_data *av8100DataTemp)
+static u16 av8100_get_ui_x4(
+ enum av8100_output_CEA_VESA output_video_format)
{
- if (AV8100_OK != av8100_send_command(av8100DataTemp->client,
- AV8100_COMMAND_DENC, I2C_INTERFACE)) {
- printk("Failed to send the AV8100_COMMAND_DENC command\n");
- }
- return;
+ return AV8100_UI_X4_DEFAULT;
}
-static void av8100_hdmi_on(struct av8100_data *av8100DataTemp)
+static int av8100_config_video_output_dep(enum av8100_output_CEA_VESA
+ output_format)
{
- int retval = AV8100_OK;
+ int retval = 0;
+ union av8100_configuration config;
+
+ /* video input */
+ config.video_input_format.dsi_input_mode =
+ AV8100_HDMI_DSI_COMMAND_MODE;
+ config.video_input_format.input_pixel_format = AV8100_INPUT_PIX_RGB565;
+ config.video_input_format.total_horizontal_pixel =
+ av8100_all_cea[output_format].htotale;
+ config.video_input_format.total_horizontal_active_pixel =
+ av8100_all_cea[output_format].hactive;
+ config.video_input_format.total_vertical_lines =
+ av8100_all_cea[output_format].vtotale;
+ config.video_input_format.total_vertical_active_lines =
+ av8100_all_cea[output_format].vactive;
+
+ switch (output_format) {
+ case AV8100_CEA5_1920X1080I_60HZ:
+ case AV8100_CEA20_1920X1080I_50HZ:
+ case AV8100_CEA21_22_576I_PAL_50HZ:
+ case AV8100_CEA6_7_NTSC_60HZ:
+ config.video_input_format.video_mode =
+ AV8100_VIDEO_INTERLACE;
+ break;
- HDMI_TRACE;
- hdmi_cmd.hdmi_mode = AV8100_HDMI_ON;
- hdmi_cmd.hdmi_format = AV8100_HDMI;
+ default:
+ config.video_input_format.video_mode =
+ AV8100_VIDEO_PROGRESSIVE;
+ break;
+ }
- retval = av8100_send_command (av8100DataTemp->client, AV8100_COMMAND_HDMI, I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_HDMI command\n");
- return;
+ config.video_input_format.nb_data_lane =
+ AV8100_DATA_LANES_USED_2;
+ config.video_input_format.nb_virtual_ch_command_mode = 0;
+ config.video_input_format.nb_virtual_ch_video_mode = 0;
+ config.video_input_format.ui_x4 = av8100_get_ui_x4(output_format);
+ config.video_input_format.TE_line_nb = av8100_get_te_line_nb(
+ output_format);
+ config.video_input_format.TE_config = AV8100_TE_IT_LINE;
+ config.video_input_format.master_clock_freq = 0;
+
+ retval = av8100_configuration_prepare(
+ AV8100_COMMAND_VIDEO_INPUT_FORMAT, &config);
+
+ /* DENC */
+ switch (output_format) {
+ case AV8100_CEA21_22_576I_PAL_50HZ:
+ config.denc_format.cvbs_video_format = AV8100_CVBS_625;
+ config.denc_format.standard_selection = AV8100_PAL_BDGHI;
+ break;
+
+ case AV8100_CEA6_7_NTSC_60HZ:
+ config.denc_format.cvbs_video_format = AV8100_CVBS_525;
+ config.denc_format.standard_selection = AV8100_NTSC_M;
+ break;
+
+ default:
+ /* Not supported */
+ break;
}
- return;
+
+ return retval;
}
-static void av8100_hdmi_off(struct av8100_data *av8100DataTemp)
+static int av8100_config_init(void)
{
- int retval = AV8100_OK;
+ int retval = 0;
+ union av8100_configuration config;
- HDMI_TRACE;
- hdmi_cmd.hdmi_mode = AV8100_HDMI_OFF;
- hdmi_cmd.hdmi_format = AV8100_HDMI;
+ printk(KERN_DEBUG "%s\n", __func__);
- retval = av8100_send_command (av8100DataTemp->client, AV8100_COMMAND_HDMI, I2C_INTERFACE);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the AV8100_COMMAND_HDMI command\n");
- return;
+ av8100_config = kzalloc(sizeof(struct av8100_config_t), GFP_KERNEL);
+ if (!av8100_config) {
+ pr_err("%s: Failed to allocate config\n", __func__);
+ return AV8100_FAIL;
}
- return;
-}
-/**
- * configure_av8100_video_input() - This function will be used to configure the video input of AV8100.
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_video_input(char* buffer_temp)
-{
- int retval = AV8100_OK;
-
- HDMI_TRACE;
- buffer_temp[0] = hdmi_video_input_cmd.dsi_input_mode;//mcde_get_dsi_mode_config();
- buffer_temp[1] = hdmi_video_input_cmd.input_pixel_format;//mcde_get_input_bpp();
- buffer_temp[2] = REG_16_8_MSB(hdmi_video_input_cmd.total_horizontal_pixel);
- buffer_temp[3] = REG_16_8_LSB(hdmi_video_input_cmd.total_horizontal_pixel);
- buffer_temp[4] = REG_16_8_MSB(hdmi_video_input_cmd.total_horizontal_active_pixel);
- buffer_temp[5] = REG_16_8_LSB(hdmi_video_input_cmd.total_horizontal_active_pixel);
-
- buffer_temp[6] = REG_16_8_MSB(hdmi_video_input_cmd.total_vertical_lines);
- buffer_temp[7] = REG_16_8_LSB(hdmi_video_input_cmd.total_vertical_lines);
- buffer_temp[8] = REG_16_8_MSB(hdmi_video_input_cmd.total_vertical_active_lines);
- buffer_temp[9] = REG_16_8_LSB(hdmi_video_input_cmd.total_vertical_active_lines);
- buffer_temp[10] = hdmi_video_input_cmd.video_mode;//mcde_get_hdmi_scan_mode();
- buffer_temp[11] = hdmi_video_input_cmd.nb_data_lane;//AV8100_DATA_LANES_USED_2;
- buffer_temp[12] = hdmi_video_input_cmd.nb_virtual_ch_command_mode;
- buffer_temp[13] = hdmi_video_input_cmd.nb_virtual_ch_video_mode;
- buffer_temp[14] = REG_16_8_MSB(hdmi_video_input_cmd.TE_line_nb);
- buffer_temp[15] = REG_16_8_LSB(hdmi_video_input_cmd.TE_line_nb);
- buffer_temp[16] = hdmi_video_input_cmd.TE_config;
- buffer_temp[17] = REG_32_8_MSB(hdmi_video_input_cmd.master_clock_freq);
- buffer_temp[18] = REG_32_8_MMSB(hdmi_video_input_cmd.master_clock_freq);
- buffer_temp[19] = REG_32_8_MLSB(hdmi_video_input_cmd.master_clock_freq);
- buffer_temp[20] = REG_32_8_LSB(hdmi_video_input_cmd.master_clock_freq);
- buffer_temp[21] = hdmi_video_input_cmd.ui_x4; /* UI value */
-
- g_av8100_cmd_length = AV8100_COMMAND_VIDEO_INPUT_FORMAT_SIZE - 1;
+ memset(&config, 0, sizeof(union av8100_configuration));
+ memset(av8100_config, 0, sizeof(union av8100_configuration));
+
+ /* Color conversion */
+ config.color_space_conversion_format.c0 = 0xFFDA;
+ config.color_space_conversion_format.c1 = 0xFFB6;
+ config.color_space_conversion_format.c2 = 0x0070;
+ config.color_space_conversion_format.c3 = 0x0042;
+ config.color_space_conversion_format.c4 = 0x0081;
+ config.color_space_conversion_format.c5 = 0x0019;
+ config.color_space_conversion_format.c6 = 0x0070;
+ config.color_space_conversion_format.c7 = 0xFFA2;
+ config.color_space_conversion_format.c8 = 0xFFEE;
+ config.color_space_conversion_format.aoffset = 0x007F;
+ config.color_space_conversion_format.boffset = 0x0010;
+ config.color_space_conversion_format.coffset = 0x007F;
+ config.color_space_conversion_format.lmax = 0xEB;
+ config.color_space_conversion_format.lmin = 0x10;
+ config.color_space_conversion_format.cmax = 0xF0;
+ config.color_space_conversion_format.cmin = 0x10;
+ retval = av8100_configuration_prepare(
+ AV8100_COMMAND_COLORSPACECONVERSION, &config);
+ if (retval)
+ return AV8100_FAIL;
+
+ /* DENC */
+ config.denc_format.cvbs_video_format = AV8100_CVBS_625;
+ config.denc_format.standard_selection = AV8100_PAL_BDGHI;
+ config.denc_format.on_off = 0;
+ config.denc_format.macrovision_on_off = 0;
+ config.denc_format.internal_generator = 0;
+
+ /* Video output */
+ config.video_output_format.video_output_cea_vesa =
+ AV8100_CEA4_1280X720P_60HZ;
+
+ retval = av8100_configuration_prepare(
+ AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, &config);
+ if (retval)
+ return AV8100_FAIL;
+
+ /* Video input */
+ av8100_config_video_output_dep(
+ config.video_output_format.video_output_cea_vesa);
+
+ /* Pattern generator */
+ config.pattern_generator_format.pattern_audio_mode =
+ AV8100_PATTERN_AUDIO_OFF;
+ config.pattern_generator_format.pattern_type =
+ AV8100_PATTERN_GENERATOR;
+ config.pattern_generator_format.pattern_video_format =
+ AV8100_PATTERN_720P;
+ retval = av8100_configuration_prepare(AV8100_COMMAND_PATTERNGENERATOR,
+ &config);
+ if (retval)
+ return AV8100_FAIL;
+
+ /* Audio input */
+ config.audio_input_format.audio_input_if_format =
+ AV8100_AUDIO_I2SDELAYED_MODE;
+ config.audio_input_format.i2s_input_nb = 1;
+ config.audio_input_format.sample_audio_freq = AV8100_AUDIO_FREQ_48KHZ;
+ config.audio_input_format.audio_word_lg = AV8100_AUDIO_16BITS;
+ config.audio_input_format.audio_format = AV8100_AUDIO_LPCM_MODE;
+ config.audio_input_format.audio_if_mode = AV8100_AUDIO_MASTER;
+ config.audio_input_format.audio_mute = AV8100_AUDIO_MUTE_DISABLE;
+ retval = av8100_configuration_prepare(
+ AV8100_COMMAND_AUDIO_INPUT_FORMAT, &config);
+ if (retval)
+ return AV8100_FAIL;
+
+ /* HDMI mode */
+ config.hdmi_format.hdmi_mode = AV8100_HDMI_ON;
+ config.hdmi_format.hdmi_format = AV8100_HDMI;
+ config.hdmi_format.dvi_format = AV8100_DVI_CTRL_CTL0;
+ retval = av8100_configuration_prepare(AV8100_COMMAND_HDMI, &config);
+ if (retval)
+ return AV8100_FAIL;
+
+ /* EDID section readback */
+ config.edid_section_readback_format.address = 0xA0;
+ config.edid_section_readback_format.block_number = 0;
+ retval = av8100_configuration_prepare(
+ AV8100_COMMAND_EDID_SECTION_READBACK, &config);
+ if (retval)
+ return AV8100_FAIL;
+
return retval;
+}
+static void av8100_config_exit(void)
+{
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ kfree(av8100_config);
+ av8100_config = NULL;
+}
+
+static void av8100_set_state(enum av8100_operating_mode state)
+{
+ g_av8100_status.av8100_state = state;
}
+
/**
- * configure_av8100_audio_output() - This function will be used to configure the audio input of AV8100.
- * @buffer_temp: configuration pointer
+ * write_single_byte() - Write a single byte to av8100
+ * through i2c interface.
+ * @client: i2c client structure
+ * @reg: register offset
+ * @data: data byte to be written
*
+ * This funtion uses smbus byte write API to write a single byte to av8100
**/
-static int configure_av8100_audio_input(char* buffer_temp)
+static int write_single_byte(struct i2c_client *client, u8 reg,
+ u8 data)
{
- int retval = AV8100_OK;
+ int ret;
- HDMI_TRACE;
- buffer_temp[0] = hdmi_audio_input_cmd.audio_input_if_format;
- buffer_temp[1] = hdmi_audio_input_cmd.i2s_input_nb;
- buffer_temp[2] = hdmi_audio_input_cmd.sample_audio_freq;
- buffer_temp[3] = hdmi_audio_input_cmd.audio_word_lg;
- buffer_temp[4] = hdmi_audio_input_cmd.audio_format;
- buffer_temp[5] = hdmi_audio_input_cmd.audio_if_mode;
- buffer_temp[6] = hdmi_audio_input_cmd.audio_mute;
+ ret = i2c_smbus_write_byte_data(client, reg, data);
+ if (ret < 0)
+ printk(KERN_DEBUG "i2c smbus write byte failed\n");
- g_av8100_cmd_length = AV8100_COMMAND_AUDIO_INPUT_FORMAT_SIZE - 1;
- return retval;
+ return ret;
}
/**
- * configure_av8100_video_output() - This function will be used to configure the video output of AV8100.
- * @buffer_temp: configuration pointer
+ * read_single_byte() - read single byte from av8100
+ * through i2c interface
+ * @client: i2c client structure
+ * @reg: register offset
+ * @val: register value
*
+ * This funtion uses smbus read block API to read single byte from the reg
+ * offset.
**/
-static int configure_av8100_video_output(char* buffer_temp)
-{
- int retval = AV8100_OK;
-
- HDMI_TRACE;
- buffer_temp[0] = hdmi_video_output_cmd.video_output_cea_vesa;
-
- if (buffer_temp[0] == AV8100_CUSTOM) {
- buffer_temp[1] = hdmi_video_output_cmd.vsync_polarity;
- buffer_temp[2] = hdmi_video_output_cmd.hsync_polarity;
- buffer_temp[3] = REG_16_8_MSB(hdmi_video_output_cmd.total_horizontal_pixel);
- buffer_temp[4] = REG_16_8_LSB(hdmi_video_output_cmd.total_horizontal_pixel);
- buffer_temp[5] = REG_16_8_MSB(hdmi_video_output_cmd.total_horizontal_active_pixel);
- buffer_temp[6] = REG_16_8_LSB(hdmi_video_output_cmd.total_horizontal_active_pixel);
- buffer_temp[7] = REG_16_8_MSB(hdmi_video_output_cmd.total_vertical_in_half_lines);
- buffer_temp[8] = REG_16_8_LSB(hdmi_video_output_cmd.total_vertical_in_half_lines);
- buffer_temp[9] = REG_16_8_MSB(hdmi_video_output_cmd.total_vertical_active_in_half_lines);
- buffer_temp[10] = REG_16_8_LSB(hdmi_video_output_cmd.total_vertical_active_in_half_lines);
- buffer_temp[11] = REG_16_8_MSB(hdmi_video_output_cmd.hsync_start_in_pixel);
- buffer_temp[12] = REG_16_8_LSB(hdmi_video_output_cmd.hsync_start_in_pixel);
- buffer_temp[13] = REG_16_8_MSB(hdmi_video_output_cmd.hsync_length_in_pixel);
- buffer_temp[14] = REG_16_8_LSB(hdmi_video_output_cmd.hsync_length_in_pixel);
- buffer_temp[15] = REG_16_8_MSB(hdmi_video_output_cmd.vsync_start_in_half_line);
- buffer_temp[16] = REG_16_8_LSB(hdmi_video_output_cmd.vsync_start_in_half_line);
- buffer_temp[17] = REG_16_8_MSB(hdmi_video_output_cmd.vsync_length_in_half_line);
- buffer_temp[18] = REG_16_8_LSB(hdmi_video_output_cmd.vsync_length_in_half_line);
- buffer_temp[19] = REG_32_8_MSB(hdmi_video_output_cmd.pixel_clock_freq_Hz);
- buffer_temp[20] = REG_32_8_MMSB(hdmi_video_output_cmd.pixel_clock_freq_Hz);
- buffer_temp[21] = REG_32_8_MLSB(hdmi_video_output_cmd.pixel_clock_freq_Hz);
- buffer_temp[22] = REG_32_8_LSB(hdmi_video_output_cmd.pixel_clock_freq_Hz);
-
- g_av8100_cmd_length = AV8100_COMMAND_VIDEO_OUTPUT_FORMAT_SIZE - 1;
- }
- else {
- g_av8100_cmd_length = 1;
+static int read_single_byte(struct i2c_client *client, u8 reg, u8 *val)
+{
+ int value;
+
+ value = i2c_smbus_read_byte_data(client, reg);
+ if (value < 0) {
+ printk(KERN_DEBUG "i2c smbus read byte failed,read data = %x "
+ "from offset:%x\n" , value, reg);
+ return AV8100_FAIL;
}
- return retval;
+ *val = (u8) value;
+ return 0;
}
/**
- * configure_av8100_video_scaling() - This function will be used to configure the video scaling params of AV8100.
- * @buffer_temp: configuration pointer
+ * write_multi_byte() - Write a multiple bytes to av8100 through
+ * i2c interface.
+ * @client: i2c client structure
+ * @buf: buffer to be written
+ * @nbytes: nunmber of bytes to be written
*
+ * This funtion uses smbus block write API's to write n number of bytes to the
+ * av8100
**/
-static int configure_av8100_video_scaling(char* buffer_temp)
+static int write_multi_byte(struct i2c_client *client, u8 reg,
+ u8 *buf, u8 nbytes)
{
- int retval = AV8100_OK;
+ int ret;
- HDMI_TRACE;
- g_av8100_cmd_length = AV8100_COMMAND_VIDEO_SCALING_FORMAT_SIZE - 1;
- return retval;
+ ret = i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf);
+ if (ret < 0)
+ printk(KERN_DEBUG "i2c smbus write multi byte error\n");
+
+ return ret;
}
-/**
- * configure_av8100_colorspace_conversion() - This function will be used to configure the color conversion params of AV8100.
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_colorspace_conversion(char* buffer_temp)
-{
- int retval = AV8100_OK;
- int i = 0;
-
- HDMI_TRACE;
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c0);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c0);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c1);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c1);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c2);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c2);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c3);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c3);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c4);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c4);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c5);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c5);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c6);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c6);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c7);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c7);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c8);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c8);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.a_offset);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.a_offset);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.b_offset);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.b_offset);
- buffer_temp[i++] = REG_16_8_MSB(hdmi_color_conversion_cmd.c_offset);
- buffer_temp[i++] = REG_16_8_LSB(hdmi_color_conversion_cmd.c_offset);
- buffer_temp[i++] = hdmi_color_conversion_cmd.l_max;
- buffer_temp[i++] = hdmi_color_conversion_cmd.l_min;
- buffer_temp[i++] = hdmi_color_conversion_cmd.c_max;
- buffer_temp[i++] = hdmi_color_conversion_cmd.c_min;
- g_av8100_cmd_length = i;
- return retval;
+static int configuration_video_input_get(char *buffer,
+ unsigned int *length)
+{
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ buffer[0] = av8100_config->hdmi_video_input_cmd.dsi_input_mode;
+ buffer[1] = av8100_config->hdmi_video_input_cmd.input_pixel_format;
+ buffer[2] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd.
+ total_horizontal_pixel);
+ buffer[3] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd.
+ total_horizontal_pixel);
+ buffer[4] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd.
+ total_horizontal_active_pixel);
+ buffer[5] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd.
+ total_horizontal_active_pixel);
+ buffer[6] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd.
+ total_vertical_lines);
+ buffer[7] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd.
+ total_vertical_lines);
+ buffer[8] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd.
+ total_vertical_active_lines);
+ buffer[9] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd.
+ total_vertical_active_lines);
+ buffer[10] = av8100_config->hdmi_video_input_cmd.video_mode;
+ buffer[11] = av8100_config->hdmi_video_input_cmd.nb_data_lane;
+ buffer[12] = av8100_config->hdmi_video_input_cmd.
+ nb_virtual_ch_command_mode;
+ buffer[13] = av8100_config->hdmi_video_input_cmd.
+ nb_virtual_ch_video_mode;
+ buffer[14] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd.
+ TE_line_nb);
+ buffer[15] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd.
+ TE_line_nb);
+ buffer[16] = av8100_config->hdmi_video_input_cmd.TE_config;
+ buffer[17] = REG_32_8_MSB(av8100_config->hdmi_video_input_cmd.
+ master_clock_freq);
+ buffer[18] = REG_32_8_MMSB(av8100_config->hdmi_video_input_cmd.
+ master_clock_freq);
+ buffer[19] = REG_32_8_MLSB(av8100_config->hdmi_video_input_cmd.
+ master_clock_freq);
+ buffer[20] = REG_32_8_LSB(av8100_config->hdmi_video_input_cmd.
+ master_clock_freq);
+ buffer[21] = av8100_config->hdmi_video_input_cmd.ui_x4;
+
+ *length = AV8100_COMMAND_VIDEO_INPUT_FORMAT_SIZE - 1;
+ return 0;
+
}
-/**
- * configure_av8100_cec_message_write() - This function will be used to configure the CEC message to AV8100.
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_cec_message_write(char* buffer_temp)
+static int configuration_audio_input_get(char *buffer,
+ unsigned int *length)
+{
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ buffer[0] = av8100_config->hdmi_audio_input_cmd.
+ audio_input_if_format;
+ buffer[1] = av8100_config->hdmi_audio_input_cmd.i2s_input_nb;
+ buffer[2] = av8100_config->hdmi_audio_input_cmd.sample_audio_freq;
+ buffer[3] = av8100_config->hdmi_audio_input_cmd.audio_word_lg;
+ buffer[4] = av8100_config->hdmi_audio_input_cmd.audio_format;
+ buffer[5] = av8100_config->hdmi_audio_input_cmd.audio_if_mode;
+ buffer[6] = av8100_config->hdmi_audio_input_cmd.audio_mute;
+
+ *length = AV8100_COMMAND_AUDIO_INPUT_FORMAT_SIZE - 1;
+ return 0;
+}
+
+static int configuration_video_output_get(char *buffer,
+ unsigned int *length)
{
- int retval = AV8100_OK;
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ buffer[0] = av8100_config->hdmi_video_output_cmd.
+ video_output_cea_vesa;
+
+ if (buffer[0] == AV8100_CUSTOM) {
+ buffer[1] = av8100_config->hdmi_video_output_cmd.
+ vsync_polarity;
+ buffer[2] = av8100_config->hdmi_video_output_cmd.
+ hsync_polarity;
+ buffer[3] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.total_horizontal_pixel);
+ buffer[4] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.total_horizontal_pixel);
+ buffer[5] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.total_horizontal_active_pixel);
+ buffer[6] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.total_horizontal_active_pixel);
+ buffer[7] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.total_vertical_in_half_lines);
+ buffer[8] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.total_vertical_in_half_lines);
+ buffer[9] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.
+ total_vertical_active_in_half_lines);
+ buffer[10] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.
+ total_vertical_active_in_half_lines);
+ buffer[11] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.hsync_start_in_pixel);
+ buffer[12] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.hsync_start_in_pixel);
+ buffer[13] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.hsync_length_in_pixel);
+ buffer[14] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.hsync_length_in_pixel);
+ buffer[15] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.vsync_start_in_half_line);
+ buffer[16] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.vsync_start_in_half_line);
+ buffer[17] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.vsync_length_in_half_line);
+ buffer[18] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.vsync_length_in_half_line);
+ buffer[19] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.hor_video_start_pixel);
+ buffer[20] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.hor_video_start_pixel);
+ buffer[21] = REG_16_8_MSB(av8100_config->
+ hdmi_video_output_cmd.vert_video_start_pixel);
+ buffer[22] = REG_16_8_LSB(av8100_config->
+ hdmi_video_output_cmd.vert_video_start_pixel);
+ buffer[23] = av8100_config->
+ hdmi_video_output_cmd.video_type;
+ buffer[24] = av8100_config->
+ hdmi_video_output_cmd.pixel_repeat;
+ buffer[25] = REG_32_8_MSB(av8100_config->
+ hdmi_video_output_cmd.pixel_clock_freq_Hz);
+ buffer[26] = REG_32_8_MMSB(av8100_config->
+ hdmi_video_output_cmd.pixel_clock_freq_Hz);
+ buffer[27] = REG_32_8_MLSB(av8100_config->
+ hdmi_video_output_cmd.pixel_clock_freq_Hz);
+ buffer[28] = REG_32_8_LSB(av8100_config->
+ hdmi_video_output_cmd.pixel_clock_freq_Hz);
+
+ *length = AV8100_COMMAND_VIDEO_OUTPUT_FORMAT_SIZE - 1;
+ } else {
+ *length = 1;
+ }
- HDMI_TRACE;
- g_av8100_cmd_length = AV8100_COMMAND_CEC_MESSAGEWRITE_SIZE;
- return retval;
+ return 0;
}
-/**
- * configure_av8100_cec_message_read() - This function will be used to read CEC message from AV8100.
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_cec_message_read(char* buffer_temp)
+static int configuration_video_scaling_get(char *buffer,
+ unsigned int *length)
{
- int retval = AV8100_OK;
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ buffer[0] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd.
+ h_start_in_pixel);
+ buffer[1] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd.
+ h_start_in_pixel);
+ buffer[2] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd.
+ h_stop_in_pixel);
+ buffer[3] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd.
+ h_stop_in_pixel);
+ buffer[4] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd.
+ v_start_in_line);
+ buffer[5] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd.
+ v_start_in_line);
+ buffer[6] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd.
+ v_stop_in_line);
+ buffer[7] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd.
+ v_stop_in_line);
+ buffer[8] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd.
+ h_start_out_pixel);
+ buffer[9] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd
+ .h_start_out_pixel);
+ buffer[10] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd.
+ h_stop_out_pixel);
+ buffer[11] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd.
+ h_stop_out_pixel);
+ buffer[12] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd.
+ v_start_out_line);
+ buffer[13] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd.
+ v_start_out_line);
+ buffer[14] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd.
+ v_stop_out_line);
+ buffer[15] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd.
+ v_stop_out_line);
+
+ *length = AV8100_COMMAND_VIDEO_SCALING_FORMAT_SIZE - 1;
+ return 0;
+}
- HDMI_TRACE;
- g_av8100_cmd_length = AV8100_COMMAND_CEC_MESSAGEREAD_BACK_SIZE;
- return retval;
+static int configuration_colorspace_conversion_get(char *buffer,
+ unsigned int *length)
+{
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ buffer[0] = REG_10_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c0);
+ buffer[1] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c0);
+ buffer[2] = REG_10_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c1);
+ buffer[3] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c1);
+ buffer[4] = REG_10_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c2);
+ buffer[5] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c2);
+ buffer[6] = REG_10_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c3);
+ buffer[7] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c3);
+ buffer[8] = REG_10_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c4);
+ buffer[9] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c4);
+ buffer[10] = REG_10_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c5);
+ buffer[11] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c5);
+ buffer[12] = REG_10_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c6);
+ buffer[13] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c6);
+ buffer[14] = REG_10_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c7);
+ buffer[15] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c7);
+ buffer[16] = REG_10_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c8);
+ buffer[17] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.c8);
+ buffer[18] = REG_16_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.aoffset);
+ buffer[19] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.aoffset);
+ buffer[20] = REG_16_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.boffset);
+ buffer[21] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.boffset);
+ buffer[22] = REG_16_8_MSB(av8100_config->
+ hdmi_color_space_conversion_cmd.coffset);
+ buffer[23] = REG_16_8_LSB(av8100_config->
+ hdmi_color_space_conversion_cmd.coffset);
+ buffer[24] = av8100_config->hdmi_color_space_conversion_cmd.lmax;
+ buffer[25] = av8100_config->hdmi_color_space_conversion_cmd.lmin;
+ buffer[26] = av8100_config->hdmi_color_space_conversion_cmd.cmax;
+ buffer[27] = av8100_config->hdmi_color_space_conversion_cmd.cmin;
+
+ *length = AV8100_COMMAND_COLORSPACECONVERSION_SIZE - 1;
+ return 0;
}
-/**
- * configure_av8100_denc() - This function will be used to configure the denc,
- * which is used for SDTV (CVBS).
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_denc(char* buffer_temp)
+static int configuration_cec_message_write_get(char *buffer,
+ unsigned int *length)
{
- int retval = AV8100_OK;
+ if (!av8100_config)
+ return AV8100_FAIL;
- HDMI_TRACE;
+ buffer[0] = av8100_config->hdmi_cec_message_write_cmd.buffer_length;
+ memcpy(&buffer[1], av8100_config->hdmi_cec_message_write_cmd.buffer,
+ HDMI_CEC_MESSAGE_WRITE_BUFFER_SIZE);
- /* Start with PAL std format */
- buffer_temp[0] = hdmi_denc_cmd.tv_lines;
- buffer_temp[1] = hdmi_denc_cmd.tv_std;
- buffer_temp[2] = hdmi_denc_cmd.denc;
- buffer_temp[3] = hdmi_denc_cmd.macrovision;
- buffer_temp[4] = hdmi_denc_cmd.internal_generator;
- buffer_temp[5] = hdmi_denc_cmd.chroma;
+ *length = AV8100_COMMAND_CEC_MESSAGE_WRITE_SIZE - 1;
+ return 0;
+}
- g_av8100_cmd_length = AV8100_COMMAND_DENC_SIZE - 1;
- return retval;
+static int configuration_cec_message_read_get(char *buffer,
+ unsigned int *length)
+{
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ /* No buffer data */
+ *length = AV8100_COMMAND_CEC_MESSAGE_READ_BACK_SIZE - 1;
+ return 0;
}
-/**
- * configure_av8100_hdmi() - This function will be used to configure the HDMI .
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_hdmi(char* buffer_temp)
+static int configuration_denc_get(char *buffer,
+ unsigned int *length)
{
- int retval = AV8100_OK;
+ if (!av8100_config)
+ return AV8100_FAIL;
- HDMI_TRACE;
- buffer_temp[0] = hdmi_cmd.hdmi_mode;
- buffer_temp[1] = hdmi_cmd.hdmi_format;
- buffer_temp[2] = hdmi_cmd.dvi_format;
+ buffer[0] = av8100_config->hdmi_denc_cmd.cvbs_video_format;
+ buffer[1] = av8100_config->hdmi_denc_cmd.standard_selection;
+ buffer[2] = av8100_config->hdmi_denc_cmd.on_off;
+ buffer[3] = av8100_config->hdmi_denc_cmd.macrovision_on_off;
+ buffer[4] = av8100_config->hdmi_denc_cmd.internal_generator;
- g_av8100_cmd_length = AV8100_COMMAND_HDMI_SIZE - 1;
- return retval;
+ *length = AV8100_COMMAND_DENC_SIZE - 1;
+ return 0;
}
-/**
- * configure_av8100_hdcp_senkey() - This function will be used to configure the hdcp send key.
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_hdcp_senkey(char* buffer_temp)
+static int configuration_hdmi_get(char *buffer, unsigned int *length)
{
- int retval = AV8100_OK;
+ if (!av8100_config)
+ return AV8100_FAIL;
- HDMI_TRACE;
- g_av8100_cmd_length = AV8100_COMMAND_HDCP_SENDKEY_SIZE;
- return retval;
+ buffer[0] = av8100_config->hdmi_cmd.hdmi_mode;
+ buffer[1] = av8100_config->hdmi_cmd.hdmi_format;
+ buffer[2] = av8100_config->hdmi_cmd.dvi_format;
+
+ *length = AV8100_COMMAND_HDMI_SIZE - 1;
+ return 0;
}
-/**
- * configure_av8100_hdcp_management() - This function will be used to configure the hdcp management.
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_hdcp_management(char* buffer_temp)
+static int configuration_hdcp_sendkey_get(char *buffer,
+ unsigned int *length)
{
- int retval = AV8100_OK;
+ if (!av8100_config)
+ return AV8100_FAIL;
- HDMI_TRACE;
- g_av8100_cmd_length = AV8100_COMMAND_HDCP_MANAGEMENT_SIZE;
- return retval;
+ buffer[0] = av8100_config->hdmi_hdcp_send_key_cmd.key_number;
+ buffer[1] = 0;
+ memcpy(&buffer[2], av8100_config->hdmi_hdcp_send_key_cmd.key,
+ HDMI_HDCP_SEND_KEY_SIZE);
+
+ *length = AV8100_COMMAND_HDCP_SENDKEY_SIZE - 1;
+ return 0;
}
-/**
- * configure_av8100_infoframe() - This function will be used to configure the info frame.
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_infoframe(char* buffer_temp)
+static int configuration_hdcp_management_get(char *buffer,
+ unsigned int *length)
+{
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ buffer[0] = av8100_config->hdmi_hdcp_management_format_cmd.
+ request_hdcp_revocation_list;
+ buffer[1] = av8100_config->hdmi_hdcp_management_format_cmd.
+ request_encrypted_transmission;
+ buffer[2] = av8100_config->hdmi_hdcp_management_format_cmd.
+ oess_eess_encryption_use;
+
+ *length = AV8100_COMMAND_HDCP_MANAGEMENT_SIZE - 1;
+ return 0;
+}
+
+static int configuration_infoframe_get(char *buffer,
+ unsigned int *length)
+{
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ buffer[0] = av8100_config->hdmi_infoframes_cmd.type;
+ buffer[1] = av8100_config->hdmi_infoframes_cmd.version;
+ buffer[2] = av8100_config->hdmi_infoframes_cmd.length;
+ buffer[3] = av8100_config->hdmi_infoframes_cmd.crc;
+ memcpy(&buffer[4], av8100_config->hdmi_infoframes_cmd.data,
+ HDMI_INFOFRAME_DATA_SIZE);
+
+ *length = AV8100_COMMAND_INFOFRAMES_SIZE - 1;
+ return 0;
+}
+
+static int av8100_edid_section_readback_get(char *buffer, unsigned int *length)
+{
+ buffer[0] = av8100_config->hdmi_edid_section_readback_cmd.address;
+ buffer[1] = av8100_config->hdmi_edid_section_readback_cmd.
+ block_number;
+
+ *length = AV8100_COMMAND_EDID_SECTION_READBACK_SIZE - 1;
+ return 0;
+}
+
+static int configuration_pattern_generator_get(char *buffer,
+ unsigned int *length)
+{
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ buffer[0] = av8100_config->hdmi_pattern_generator_cmd.pattern_type;
+ buffer[1] = av8100_config->hdmi_pattern_generator_cmd.
+ pattern_video_format;
+ buffer[2] = av8100_config->hdmi_pattern_generator_cmd.
+ pattern_audio_mode;
+
+ *length = AV8100_COMMAND_PATTERNGENERATOR_SIZE - 1;
+ return 0;
+}
+
+static int configuration_fuse_aes_key_get(char *buffer,
+ unsigned int *length)
{
- int retval = AV8100_OK;
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ buffer[0] = av8100_config->hdmi_fuse_aes_key_cmd.fuse_operation;
+ memcpy(&buffer[1], av8100_config->hdmi_fuse_aes_key_cmd.key,
+ HDMI_FUSE_AES_KEY_SIZE);
+
+ *length = AV8100_COMMAND_FUSE_AES_KEY_SIZE - 1;
+ return 0;
+}
+
+static int get_command_return_data(struct i2c_client *i2c,
+ enum av8100_command_type command_type,
+ u8 *command_buffer,
+ u8 *buffer_length,
+ u8 *buffer)
+{
+ int retval = 0;
+ char val;
+ int index = 0;
+
+ /* Get the first return byte */
+ retval = read_single_byte(i2c, AV8100_COMMAND_OFFSET, &val);
+ if (retval)
+ goto get_command_return_data_fail;
+
+ if (val != (0x80 | command_type)) {
+ retval = AV8100_FAIL;
+ goto get_command_return_data_fail;
+ }
+
+ switch (command_type) {
+ case AV8100_COMMAND_VIDEO_INPUT_FORMAT:
+ case AV8100_COMMAND_AUDIO_INPUT_FORMAT:
+ case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT:
+ case AV8100_COMMAND_VIDEO_SCALING_FORMAT:
+ case AV8100_COMMAND_COLORSPACECONVERSION:
+ case AV8100_COMMAND_CEC_MESSAGE_WRITE:
+ case AV8100_COMMAND_DENC:
+ case AV8100_COMMAND_HDMI:
+ case AV8100_COMMAND_HDCP_SENDKEY:
+ case AV8100_COMMAND_INFOFRAMES:
+ case AV8100_COMMAND_PATTERNGENERATOR:
+ /* Get the second return byte */
+ retval = read_single_byte(i2c,
+ AV8100_COMMAND_OFFSET + 1, &val);
+ if (retval)
+ goto get_command_return_data_fail;
+
+ if (val) {
+ retval = AV8100_FAIL;
+ goto get_command_return_data_fail;
+ }
+ break;
+
+ case AV8100_COMMAND_CEC_MESSAGE_READ_BACK:
+ if ((buffer == NULL) || (buffer_length == NULL)) {
+ retval = AV8100_FAIL;
+ goto get_command_return_data_fail;
+ }
+
+ /* Get the return buffer length */
+ retval = read_single_byte(i2c,
+ AV8100_COMMAND_OFFSET + 3, &val);
+ if (retval)
+ goto get_command_return_data_fail;
+
+ *buffer_length = val;
+
+ if (*buffer_length >
+ HDMI_CEC_MESSAGE_READBACK_MAXSIZE) {
+ printk(KERN_DEBUG "CEC size too large %d\n",
+ *buffer_length);
+ *buffer_length = HDMI_CEC_MESSAGE_READBACK_MAXSIZE;
+ }
+
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "return data: ");
+#endif
+
+ /* Get the return buffer */
+ for (index = 0; index < *buffer_length; ++index) {
+ retval = read_single_byte(i2c,
+ AV8100_COMMAND_OFFSET + 4 + index,
+ &val);
+ if (retval) {
+ *buffer_length = 0;
+ goto get_command_return_data_fail;
+ } else {
+ *(buffer + index) = val;
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "%02x ", *(buffer + index));
+#endif
+ }
+ }
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "\n");
+#endif
+ break;
+
+ case AV8100_COMMAND_HDCP_MANAGEMENT:
+ if ((buffer == NULL) || (buffer_length == NULL) ||
+ (command_buffer == NULL)) {
+ retval = AV8100_FAIL;
+ goto get_command_return_data_fail;
+ }
+
+ /* Get the second return byte */
+ retval = read_single_byte(i2c,
+ AV8100_COMMAND_OFFSET + 1, &val);
+ if (retval) {
+ goto get_command_return_data_fail;
+ } else {
+ /* Check the second return byte */
+ if (val)
+ goto get_command_return_data_fail;
+ }
+
+ /* Get the return buffer length */
+ if (command_buffer[0] ==
+ HDMI_REQUEST_FOR_REVOCATION_LIST_INPUT) {
+ *buffer_length = 0x1F;
+ } else {
+ *buffer_length = 0x0;
+ }
+
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "return data: ");
+#endif
+ /* Get the return buffer */
+ for (index = 0; index < *buffer_length; ++index) {
+ retval = read_single_byte(i2c,
+ AV8100_COMMAND_OFFSET + 2 + index,
+ &val);
+ if (retval) {
+ *buffer_length = 0;
+ goto get_command_return_data_fail;
+ } else {
+ *(buffer + index) = val;
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "%02x ", *(buffer + index));
+#endif
+ }
+ }
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "\n");
+#endif
+ break;
+
+ case AV8100_COMMAND_EDID_SECTION_READBACK:
+ if ((buffer == NULL) || (buffer_length == NULL)) {
+ retval = AV8100_FAIL;
+ goto get_command_return_data_fail;
+ }
+
+ /* Return buffer length is fixed */
+ *buffer_length = 0x80;
+
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "return data: ");
+#endif
+ /* Get the return buffer */
+ for (index = 0; index < *buffer_length; ++index) {
+ retval = read_single_byte(i2c,
+ AV8100_COMMAND_OFFSET + 1 + index,
+ &val);
+ if (retval) {
+ *buffer_length = 0;
+ goto get_command_return_data_fail;
+ } else {
+ *(buffer + index) = val;
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "%02x ", *(buffer + index));
+#endif
+ }
+ }
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "\n");
+#endif
+ break;
+
+ case AV8100_COMMAND_FUSE_AES_KEY:
+ if ((buffer == NULL) || (buffer_length == NULL)) {
+ retval = AV8100_FAIL;
+ goto get_command_return_data_fail;
+ }
+
+ /* Get the second return byte */
+ retval = read_single_byte(i2c,
+ AV8100_COMMAND_OFFSET + 1, &val);
+ if (retval)
+ goto get_command_return_data_fail;
+
+ /* Check the second return byte */
+ if (val) {
+ retval = AV8100_FAIL;
+ goto get_command_return_data_fail;
+ }
+
+ /* Return buffer length is fixed */
+ *buffer_length = 0x2;
+
+ /* Get CRC */
+ retval = read_single_byte(i2c,
+ AV8100_COMMAND_OFFSET + 1, &val);
+ if (retval)
+ goto get_command_return_data_fail;
+
+ *(buffer + 0) = val;
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "CRC:%02x ", val);
+#endif
+
+ /* Get programmed status */
+ retval = read_single_byte(i2c,
+ AV8100_COMMAND_OFFSET + 1, &val);
+ if (retval)
+ goto get_command_return_data_fail;
+
+ *(buffer + 1) = val;
+#ifdef AV8100_DEBUG_EXTRA
+ printk(KERN_DEBUG "programmed:%02x ", val);
+#endif
+ break;
+
+ default:
+ retval = AV8100_INVALID_COMMAND;
+ break;
+ }
- HDMI_TRACE;
- g_av8100_cmd_length = AV8100_COMMAND_INFOFRAMES_SIZE;
+ return retval;
+get_command_return_data_fail:
+ printk(KERN_DEBUG "get_command_return_data FAIL\n");
return retval;
}
-/**
- * configure_av8100_pattern_generator() - This function will be used to configure the pattern generator.
- * @buffer_temp: configuration pointer
- *
- **/
-static int configure_av8100_pattern_generator(char* buffer_temp)
+int av8100_powerup(void)
{
- int retval = AV8100_OK;
+ int retval = 0;
+ struct i2c_client *i2c;
+ u8 cpd;
+ u8 stby;
+ u8 hpds;
+ u8 cpds;
+ u8 mclkrng;
+ u8 off_time;
+ u8 on_time;
+ u8 fdl;
+ u8 hld;
+ u8 wa;
+ u8 ra;
+
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ i2c = av8100_config->client;
+
+ /* Reset av8100 */
+ gpio_set_value(GPIO_AV8100_RSTN, 1);
+ av8100_set_state(AV8100_OPMODE_STANDBY);
+
+ /* Master clock timing, running, search for plug */
+ retval = av8100_register_standby_write(AV8100_STANDBY_CPD_HIGH,
+ AV8100_STANDBY_STBY_HIGH, AV8100_MASTER_CLOCK_TIMING);
+ if (retval) {
+ pr_err("Failed to write the value to av8100 register\n");
+ return -EFAULT;
+ }
+
+ retval = av8100_register_standby_read(&cpd, &stby, &hpds, &cpds,
+ &mclkrng);
+ if (retval) {
+ pr_err("Failed to read the value from av8100 register\n");
+ return -EFAULT;
+ } else {
+ printk(KERN_DEBUG "STANDBY_REG register cpd:%d stby:%d "
+ "hpds:%d cpds:%d mclkrng:%0x\n", cpd, stby, hpds,
+ cpds, mclkrng);
+ }
+
+ /* ON time & OFF time on 5v HDMI plug detect */
+ retval = av8100_register_hdmi_5_volt_time_write(AV8100_OFF_TIME,
+ AV8100_ON_TIME);
+ if (retval) {
+ pr_err("Failed to write the value to av8100 register\n");
+ return -EFAULT;
+ }
+
+ retval = av8100_register_hdmi_5_volt_time_read(&off_time, &on_time);
+ if (retval) {
+ pr_err("Failed to read the value from av8100 register\n");
+ return -EFAULT;
+ } else {
+ printk(KERN_DEBUG "AV8100_5_VOLT_TIME_REG register "
+ "off_time:%0x on_time:%0x\n", off_time, on_time);
+ }
+
+ /* Device in hold mode, enable firmware download*/
+ retval = av8100_register_general_control_write(
+ AV8100_GENERAL_CONTROL_FDL_HIGH,
+ AV8100_GENERAL_CONTROL_HLD_HIGH,
+ AV8100_GENERAL_CONTROL_WA_LOW,
+ AV8100_GENERAL_CONTROL_RA_LOW);
+ if (retval) {
+ pr_err("Failed to write the value to av8100 register\n");
+ return -EFAULT;
+ }
- HDMI_TRACE;
- buffer_temp[0] = hdmi_pattern_generator_cmd.pattern_type;
- buffer_temp[1] = hdmi_pattern_generator_cmd.pattern_video_format;
- buffer_temp[2] = hdmi_pattern_generator_cmd.pattern_audio_mode;
+ retval = av8100_register_general_control_read(&fdl, &hld, &wa, &ra);
+ if (retval) {
+ pr_err("Failed to read the value from av8100 register\n");
+ return -EFAULT;
+ } else {
+ printk(KERN_DEBUG "GENERAL_CONTROL_REG register fdl:%d "
+ "hld:%d wa:%d ra:%d\n", fdl, hld, wa, ra);
+ }
- g_av8100_cmd_length = AV8100_COMMAND_PATTERNGENERATOR_SIZE - 1;
+ av8100_set_state(AV8100_OPMODE_SCAN);
return retval;
}
-/**
- * read_edid_info() - This function will be used to EDID info.
- * @i2c: i2c client device
- * @buff: pointer to EDID buffer
- *
- **/
-#if 0
-static int read_edid_info(struct i2c_client *i2c, char* buff)
+int av8100_powerdown(void)
{
-int retval = AV8100_OK;
-return retval;
+ gpio_set_value(GPIO_AV8100_RSTN, 0);
+ av8100_set_state(AV8100_OPMODE_SHUTDOWN);
+
+ return 0;
}
-#endif
-/**
- * av8100_download_firmware() - This function will be used to download firmware.
- * @i2c: i2c client device
- * @fw_buff: pointer to firmware buffer
- * @numOfBytes: number of bytes
- *
- **/
-static int av8100_download_firmware(struct i2c_client *i2c, char regOffset, char* fw_buff, int numOfBytes, enum interface if_type)
+int av8100_download_firmware(char *fw_buff, int nbytes,
+ enum interface_type if_type)
{
- int retval = AV8100_OK;
+ int retval = 0;
int temp = 0x0;
- int increment = 15, index = 0;
- int size = 0x0, tempnext = 0x0;
- char val = 0x0 ;
+ int increment = 15;
+ int index = 0;
+ int size = 0x0;
+ int tempnext = 0x0;
+ char val = 0x0;
char CheckSum = 0;
int cnt = 10;
+ struct i2c_client *i2c;
+ u8 cecrec;
+ u8 cectrx;
+ u8 uc;
+ u8 onuvb;
+ u8 hdcps;
+
+ if (!av8100_config) {
+ retval = AV8100_FAIL;
+ goto av8100_download_firmware_out;
+ }
- temp = numOfBytes % increment;
- for(size=0;size<(numOfBytes-temp);size=size+increment, index+=increment)
- {
- if(if_type == I2C_INTERFACE) {
- retval = av8100_write_multi_byte(i2c, regOffset, fw_buff + size, increment);
- if(retval != AV8100_OK) {
- printk("Failed to download the av8100 firmware\n");
- return -EFAULT;
- }
- }
- else if(if_type == DSI_INTERFACE) {
- retval = dsiLPdcslongwrite(0, 0x10, DCS_FW_DOWNLOAD,fw_buff[index],fw_buff[index + 1],fw_buff[index + 2],
- fw_buff[index + 3],fw_buff[index + 4],fw_buff[index + 5],fw_buff[index + 6],fw_buff[index + 7], fw_buff[index + 8],
- fw_buff[index + 9],fw_buff[index + 10],fw_buff[index + 11],fw_buff[index + 12],fw_buff[index + 13], fw_buff[index + 14],
- CHANNEL_A, DSI_LINK2);
- if(retval != AV8100_OK) {
- printk("Failed to send the data through dsi interface\n");
- return retval;
+ if (fw_buff == NULL) {
+ /* use default fw buffer */
+ fw_buff = av8100_fw_buff;
+ nbytes = AV8100_FW_SIZE;
+ }
+
+ i2c = av8100_config->client;
+
+ LOCK_AV8100_HW;
+
+ temp = nbytes % increment;
+ for (size = 0; size < (nbytes-temp); size = size + increment,
+ index += increment) {
+ if (if_type == I2C_INTERFACE) {
+ retval = write_multi_byte(i2c,
+ AV8100_FIRMWARE_DOWNLOAD_ENTRY, fw_buff + size,
+ increment);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to download the "
+ "av8100 firmware\n");
+ retval = -EFAULT;
+ UNLOCK_AV8100_HW;
+ goto av8100_download_firmware_out;
}
+ } else if (if_type == DSI_INTERFACE) {
+ printk(KERN_DEBUG "DSI_INTERFACE is currently not supported\n");
+ UNLOCK_AV8100_HW;
+ goto av8100_download_firmware_out;
+ } else {
+ retval = AV8100_INVALID_INTERFACE;
+ UNLOCK_AV8100_HW;
+ goto av8100_download_firmware_out;
}
- else
- return AV8100_INVALID_INTERFACE;
- for(tempnext=size;tempnext<(increment+size);tempnext++)
- ReceiveTab[tempnext] = fw_buff[tempnext];
+ for (tempnext = size; tempnext < (increment+size); tempnext++)
+ av8100_receivetab[tempnext] = fw_buff[tempnext];
}
- // Transfer last firmware bytes
- if(if_type == I2C_INTERFACE) {
- retval = av8100_write_multi_byte(i2c, regOffset, fw_buff + size, temp);
- if(retval != AV8100_OK) {
- printk("Failed to download the av8100 firmware\n");
- return -EFAULT;
- }
- }
- else if(if_type == DSI_INTERFACE) {
- retval = dsiLPdcslongwrite(0, temp+1, DCS_FW_DOWNLOAD,fw_buff[index],fw_buff[index + 1],fw_buff[index + 2],
- fw_buff[index + 3],fw_buff[index + 4],fw_buff[index + 5],fw_buff[index + 6],fw_buff[index + 7], fw_buff[index + 8],
- fw_buff[index + 9],fw_buff[index + 10],fw_buff[index + 11],fw_buff[index + 12],fw_buff[index + 13], fw_buff[index + 14],
- CHANNEL_A, DSI_LINK2);
-
- if(retval != AV8100_OK) {
- printk("Failed to send the data through dsi interface\n");
- return retval;
+ /* Transfer last firmware bytes */
+ if (if_type == I2C_INTERFACE) {
+ retval = write_multi_byte(i2c,
+ AV8100_FIRMWARE_DOWNLOAD_ENTRY, fw_buff + size, temp);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to download the av8100 firmware\n");
+ retval = -EFAULT;
+ UNLOCK_AV8100_HW;
+ goto av8100_download_firmware_out;
}
+ } else if (if_type == DSI_INTERFACE) {
+ /* TODO: Add support for DSI firmware download */
+ retval = AV8100_INVALID_INTERFACE;
+ UNLOCK_AV8100_HW;
+ goto av8100_download_firmware_out;
+ } else {
+ retval = AV8100_INVALID_INTERFACE;
+ UNLOCK_AV8100_HW;
+ goto av8100_download_firmware_out;
}
- else
- return AV8100_INVALID_INTERFACE;
- for(tempnext=size;tempnext<(size+temp);tempnext++) {
- ReceiveTab[tempnext] = fw_buff[tempnext];
- }
+ for (tempnext = size; tempnext < (size+temp); tempnext++)
+ av8100_receivetab[tempnext] = fw_buff[tempnext];
- // check transfer
- for(size=0;size<numOfBytes;size++) {
+ /* check transfer*/
+ for (size = 0; size < nbytes; size++) {
CheckSum = CheckSum ^ fw_buff[size];
- if(ReceiveTab[size] != fw_buff[size]) {
- printk(">Fw download fail....i=%d\n",size);
- printk("Transm = %x, Receiv = %x\n",fw_buff[size],ReceiveTab[size]);
+ if (av8100_receivetab[size] != fw_buff[size]) {
+ printk(KERN_DEBUG ">Fw download fail....i=%d\n", size);
+ printk(KERN_DEBUG "Transm = %x, Receiv = %x\n",
+ fw_buff[size], av8100_receivetab[size]);
}
}
- retval = av8100_read_single_byte(i2c, regOffset, &val);
- if(retval != AV8100_OK) {
- printk("Failed to read the value in to the av8100 register\n");
- return -EFAULT;
+ UNLOCK_AV8100_HW;
+
+ retval = av8100_register_firmware_download_entry_read(&val);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to read the value from the av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_download_firmware_out;
}
- printk("CheckSum:%x,val:%x\n",CheckSum,val);
+ printk(KERN_DEBUG "CheckSum:%x,val:%x\n", CheckSum, val);
- if(CheckSum != val) {
- printk(">Fw downloading.... FAIL CheckSum issue\n");
- printk("Checksum = %d\n",CheckSum);
- printk("Checksum read: %d\n",val);
- return AV8100_FWDOWNLOAD_FAIL;
+ if (CheckSum != val) {
+ printk(KERN_DEBUG ">Fw downloading.... FAIL CheckSum issue\n");
+ printk(KERN_DEBUG "Checksum = %d\n", CheckSum);
+ printk(KERN_DEBUG "Checksum read: %d\n", val);
+ retval = AV8100_FWDOWNLOAD_FAIL;
+ goto av8100_download_firmware_out;
+ } else {
+ printk(KERN_DEBUG ">Fw downloading.... success\n");
}
- else
- printk(">Fw downloading.... success\n");
/* Set to idle mode */
- retval = av8100_write_single_byte(i2c, GENERAL_CONTROL_REG, 0x0);
- if(retval != AV8100_OK) {
- printk("Failed to write the value in to the av8100 registers\n");
- return -EFAULT;
+ av8100_register_general_control_write(AV8100_GENERAL_CONTROL_FDL_LOW,
+ AV8100_GENERAL_CONTROL_HLD_LOW, AV8100_GENERAL_CONTROL_WA_LOW,
+ AV8100_GENERAL_CONTROL_RA_LOW);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to write the value to the av8100 registers\n");
+ retval = -EFAULT;
+ goto av8100_download_firmware_out;
}
/* Wait Internal Micro controler ready */
cnt = 3;
- retval = av8100_read_single_byte(i2c, GENERAL_STATUS_REG, &val);
- while((retval == AV8100_OK) && (val != AV8100_GENERAL_STATUS_UC_READY) && (cnt-- > 0)) {
- printk("av8100 wait2\n");
+ retval = av8100_register_general_status_read(&cecrec, &cectrx, &uc,
+ &onuvb, &hdcps);
+ while ((retval == 0) && (uc != 0x1) && (cnt-- > 0)) {
+ printk(KERN_DEBUG "av8100 wait2\n");
/* TODO */
- for(temp=0;temp<0xFFFFF;temp++);
+ for (temp = 0; temp < 0xFFFFF; temp++)
+ ;
- retval = av8100_read_single_byte(i2c, GENERAL_STATUS_REG, &val);
+ retval = av8100_register_general_status_read(&cecrec, &cectrx,
+ &uc, &onuvb, &hdcps);
}
- if(retval != AV8100_OK) {
- printk("Failed to read the value in to the av8100 register\n");
- return -EFAULT;
+ if (retval) {
+ printk(KERN_DEBUG "Failed to read the value from the av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_download_firmware_out;
}
av8100_set_state(AV8100_OPMODE_IDLE);
+
+av8100_download_firmware_out:
return retval;
}
-/**
- * av8100_send_command() - This function will be used to send the command to AV8100.
- * @i2cClient: i2c client device
- * @command_type: command type
- * @if_type: interface type.
- *
- **/
-static int av8100_send_command (struct i2c_client *i2cClient, char command_type, enum interface if_type)
+int av8100_disable_interrupt(void)
{
- int retval = AV8100_OK, temp = 0, index = 0;
- char val = 0x0, val1 = 0x0;
- //char val2 = 0x0, val3 = 0x0;
- int reg_offset = AV8100_COMMAND_OFFSET + 1;
- char buffer[AV8100_COMMAND_MAX_LENGTH];
+ int retval;
+ struct i2c_client *i2c;
- g_av8100_cmd_length=0;
- memset(buffer, 0x00, AV8100_COMMAND_MAX_LENGTH);
- switch(command_type)
- {
- case AV8100_COMMAND_VIDEO_INPUT_FORMAT:
- configure_av8100_video_input(buffer);
- break;
- case AV8100_COMMAND_AUDIO_INPUT_FORMAT:
- configure_av8100_audio_input(buffer);
- break;
- case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT:
- configure_av8100_video_output(buffer);
- break;
- case AV8100_COMMAND_VIDEO_SCALING_FORMAT:
- configure_av8100_video_scaling(buffer);
- break;
- case AV8100_COMMAND_COLORSPACECONVERSION:
- configure_av8100_colorspace_conversion(buffer);
- break;
- case AV8100_COMMAND_CEC_MESSAGEWRITE:
- configure_av8100_cec_message_write(buffer);
- break;
- case AV8100_COMMAND_CEC_MESSAGEREAD_BACK:
- configure_av8100_cec_message_read(buffer);
- break;
- case AV8100_COMMAND_DENC:
- configure_av8100_denc(buffer);
- break;
- case AV8100_COMMAND_HDMI:
- configure_av8100_hdmi(buffer);
- break;
- case AV8100_COMMAND_HDCP_SENDKEY:
- configure_av8100_hdcp_senkey(buffer);
- break;
- case AV8100_COMMAND_HDCP_MANAGEMENT:
- configure_av8100_hdcp_management(buffer);
- break;
- case AV8100_COMMAND_INFOFRAMES:
- configure_av8100_infoframe(buffer);
- break;
- case AV8100_COMMAND_EDID_SECTIONREADBACK:
- break;
- case AV8100_COMMAND_PATTERNGENERATOR:
- configure_av8100_pattern_generator(buffer);
- break;
- default:
- printk(KERN_INFO "Invalid command type\n");
- retval = AV8100_INVALID_COMMAND;
+ if (!av8100_config) {
+ retval = AV8100_FAIL;
+ goto av8100_disable_interrupt_out;
+ }
+ i2c = av8100_config->client;
+
+ retval = av8100_register_standby_pending_interrupt_write(
+ AV8100_STANDBY_PENDING_INTERRUPT_HPDI_LOW,
+ AV8100_STANDBY_PENDING_INTERRUPT_CPDI_LOW,
+ AV8100_STANDBY_PENDING_INTERRUPT_ONI_LOW);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to write the value to av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_disable_interrupt_out;
}
-#ifdef HDMI_LOGGING
- PRNK_COL(PRNK_COL_YELLOW);
- printk(KERN_DEBUG "HDMI send cmd parameters: ");
- { int i;
- for (i = 0; i < g_av8100_cmd_length; i++)
- printk("0x%02x ", buffer[i]);
+ retval = av8100_register_general_interrupt_mask_write(
+ AV8100_GENERAL_INTERRUPT_MASK_EOCM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_VSIM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_VSOM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_CECM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_HDCPM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_UOVBM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_TEM_LOW);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to write the value to av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_disable_interrupt_out;
}
- printk("\n");
- printk(KERN_DEBUG "HDMI send cmd: 0x%02x\n", command_type);
- PRNK_COL(PRNK_COL_WHITE);
-#endif /* HDMI_LOGGING */
- if(if_type == I2C_INTERFACE)
- {
- /* writing the command configuration */
- retval = av8100_write_multi_byte(i2cClient, reg_offset, buffer, g_av8100_cmd_length);
- if(retval != AV8100_OK)
- return retval;
- /* writing the command */
- retval = av8100_write_single_byte(i2cClient, AV8100_COMMAND_OFFSET, command_type);
- if(retval != AV8100_OK)
- return retval;
- mdelay(10);
- retval = av8100_read_single_byte(i2cClient, AV8100_COMMAND_OFFSET, &val);
- if(retval != AV8100_OK)
- return retval;
+ retval = av8100_register_standby_interrupt_mask_write(
+ AV8100_STANDBY_INTERRUPT_MASK_HPDM_LOW,
+ AV8100_STANDBY_INTERRUPT_MASK_CPDM_LOW,
+ AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT,
+ AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to write the value to av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_disable_interrupt_out;
+ }
- if(val != (0x80 | command_type)) //0x10 == 0x80 | Identifier
- return AV8100_COMMAND_FAIL;
+#ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS
+ del_timer(&av8100_timer);
+#endif
- retval = av8100_read_single_byte(i2cClient, AV8100_COMMAND_OFFSET+1, &val1);
- if(retval != AV8100_OK)
- return retval;
+av8100_disable_interrupt_out:
+ return retval;
+}
- if(val1 != AV8100_OK) // 0x11
- return AV8100_COMMAND_FAIL;
+int av8100_enable_interrupt(void)
+{
+ int retval;
+ struct i2c_client *i2c;
+ if (!av8100_config) {
+ retval = AV8100_FAIL;
+ goto av8100_enable_interrupt_out;
+ }
- }else
- if(if_type == DSI_INTERFACE)
- {
- get_dcs_data_index_params();
- for (temp = 0, index = 0; temp < g_dcs_data_count_index; temp++, /*index++*/ index +=15)
- {
-#if 0
- retval = dsiLPdcslongwrite(0, 0x10, DCS_WRITE_UC,buffer[index],buffer[++index],buffer[++index],
- buffer[++index],buffer[++index],buffer[++index],buffer[++index],buffer[++index], buffer[++index],
- buffer[++index],buffer[++index],buffer[++index],buffer[++index],buffer[++index], buffer[++index],
- CHANNEL_A, DSI_LINK2);
-
- if(retval != AV8100_OK)
- {
- printk("Failed to send the data through dsi interface\n");
- return retval;
- }
-#endif
- mcde_send_hdmi_cmd_data(&buffer[index],0x10, DCS_WRITE_UC);
+ i2c = av8100_config->client;
- }
- if(g_dcs_data_count_last != 0)
- {
-#if 0
- retval = dsiLPdcslongwrite(0, g_dcs_data_count_last+1, DCS_WRITE_UC,buffer[index],buffer[++index],buffer[++index],
- buffer[++index],buffer[++index],buffer[++index],buffer[++index],buffer[++index], buffer[++index],
- buffer[++index],buffer[++index],buffer[++index],buffer[++index],buffer[++index], buffer[++index],
- CHANNEL_A, DSI_LINK2);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the data through dsi interface\n");
- return retval;
- }
-#endif
+ retval = av8100_register_standby_pending_interrupt_write(
+ AV8100_STANDBY_PENDING_INTERRUPT_HPDI_LOW,
+ AV8100_STANDBY_PENDING_INTERRUPT_CPDI_LOW,
+ AV8100_STANDBY_PENDING_INTERRUPT_ONI_LOW);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to write the value to av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_enable_interrupt_out;
+ }
- mcde_send_hdmi_cmd_data(&buffer[index],g_dcs_data_count_last+1, DCS_WRITE_UC);
- }
-#if 0
- retval = dsiLPdcsshortwrite1parm(0, DCS_EXEC_UC,command_type, CHANNEL_A, DSI_LINK2);
- if(retval != AV8100_OK)
- {
- printk("Failed to send the command through dsi interface\n");
- return retval;
- }
-#endif
-#if 0
- mcde_send_hdmi_cmd(&command_type,2, DCS_EXEC_UC);
- dsireaddata(&val, &val1, &val2, &val3, CHANNEL_A, DSI_LINK2);
- printk("data read from dsi val:%x, val1:%x\n",val, val1);
- if(val != (0x80 | command_type)) //0x10 == 0x80 | Identifier
- return AV8100_COMMAND_FAIL;
- if(val1 != AV8100_OK) // 0x11
- return AV8100_COMMAND_FAIL;
- mcde_send_hdmi_cmd(&command_type,2, DCS_EXEC_UC);
-#endif
-#if 0
- /* writing the command */
- retval = av8100_write_single_byte(i2cClient, AV8100_COMMAND_OFFSET, command_type);
- if(retval != AV8100_OK)
- return retval;
+ retval = av8100_register_general_interrupt_mask_write(
+ AV8100_GENERAL_INTERRUPT_MASK_EOCM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_VSIM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_VSOM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_CECM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_HDCPM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_UOVBM_LOW,
+ AV8100_GENERAL_INTERRUPT_MASK_TEM_HIGH);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to write the value to av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_enable_interrupt_out;
+ }
+
+ retval = av8100_register_standby_interrupt_mask_write(
+ AV8100_STANDBY_INTERRUPT_MASK_HPDM_LOW,
+ AV8100_STANDBY_INTERRUPT_MASK_CPDM_LOW,
+ AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT,
+ AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to write the value to av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_enable_interrupt_out;
+ }
+
+#ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS
+ init_timer(&av8100_timer);
+ av8100_timer.expires = jiffies + AV8100_TIMER_INTERRUPT_POLLING_TIME;
+ av8100_timer.function = av8100_timer_int;
+ av8100_timer.data = 0;
+ add_timer(&av8100_timer);
#endif
- mcde_send_hdmi_cmd(&command_type,2, DCS_EXEC_UC);
- mdelay(10);
- retval = av8100_read_single_byte(i2cClient, AV8100_COMMAND_OFFSET, &val);
- if(retval != AV8100_OK)
- return retval;
- printk("value:%x\n", val);
- if(val != (0x80 | command_type)) //0x10 == 0x80 | Identifier
- return AV8100_COMMAND_FAIL;
- retval = av8100_read_single_byte(i2cClient, AV8100_COMMAND_OFFSET+1, &val1);
- if(retval != AV8100_OK)
- return retval;
-printk("value1:%x\n", val1);
- if(val1 != AV8100_OK) // 0x11
- return AV8100_COMMAND_FAIL;
+av8100_enable_interrupt_out:
+ return retval;
+}
-printk("sending command is successful!!!val:%x, val1:%x\n", val, val1);
- }else
- {
- retval = AV8100_INVALID_INTERFACE;
- printk(KERN_INFO "Invalid command type\n");
+static int register_write_internal(u8 offset, u8 value)
+{
+ int retval;
+ struct i2c_client *i2c;
+
+ if (!av8100_config) {
+ retval = AV8100_FAIL;
+ goto av8100_register_write_out;
+ }
+
+ i2c = av8100_config->client;
+
+ /* Write to register */
+ retval = write_single_byte(i2c, offset, value);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to write the value to av8100 register\n");
+ retval = -EFAULT;
}
+
+av8100_register_write_out:
return retval;
}
-/**
- *
- * av8100_powerdown() - This function will be used to powerdown the AV8100.
- * @i2c: i2c client device
- * @id: device id
- *
- **/
-static int av8100_powerdown(void)
+int av8100_register_standby_write(
+ u8 cpd, u8 stby, u8 mclkrng)
{
- int retval = AV8100_OK;
+ int retval;
+ u8 val;
- /** reset the av8100 */
- gpio_set_value(GPIO_AV8100_RSTN,GPIO_LOW);
+ LOCK_AV8100_HW;
- av8100_set_state(AV8100_OPMODE_SHUTDOWN);
+ /* Set register value */
+ val = AV8100_STANDBY_CPD(cpd) | AV8100_STANDBY_STBY(stby) |
+ AV8100_STANDBY_MCLKRNG(mclkrng);
+
+ /* Write to register */
+ retval = register_write_internal(AV8100_STANDBY, val);
+ UNLOCK_AV8100_HW;
return retval;
}
-/**
- *
- * av8100_powerup() - This function will be used to powerup the AV8100.
- * @i2c: i2c client device
- * @id: device id
- *
- **/
-static int av8100_powerup(struct i2c_client *i2c, const struct i2c_device_id *id)
+int av8100_register_hdmi_5_volt_time_write(u8 off_time, u8 on_time)
{
- int retval = AV8100_OK;
- char val = 0x0;
+ int retval;
+ u8 val;
- /* configuration length */
- g_av8100_cmd_length = 6;
- /** reset the av8100 */
- gpio_set_value(GPIO_AV8100_RSTN, 1);
- av8100_set_state(AV8100_OPMODE_STANDBY);
+ LOCK_AV8100_HW;
- retval = av8100_write_single_byte(i2c, STANDBY_REG, 0x3B); /* Device runing, master clock = 38.4Mhz, Enable searching CVBS cable*/
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to av8100 register\n");
- return -EFAULT;
- }
+ /* Set register value */
+ val = AV8100_HDMI_5_VOLT_TIME_OFF_TIME(off_time) |
+ AV8100_HDMI_5_VOLT_TIME_ON_TIME(on_time);
- retval = av8100_read_single_byte(i2c, STANDBY_REG, &val);
- if(retval != AV8100_OK)
- {
- printk("Failed to read the value in to av8100 register\n");
- return -EFAULT;
- }else
- printk("STANDBY_REG register value:%0x\n",val);
+ /* Write to register */
+ retval = register_write_internal(AV8100_HDMI_5_VOLT_TIME, val);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- retval = av8100_write_single_byte(i2c, AV8100_5_VOLT_TIME_REG, 0x20); /* Define ON TIME & OFF time on 5v HDMI plug detect*/
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to av8100 register\n");
- return -EFAULT;
+int av8100_register_standby_interrupt_mask_write(
+ u8 hpdm, u8 cpdm, u8 stbygpiocfg, u8 ipol)
+{
+ int retval;
+ u8 val;
+
+ LOCK_AV8100_HW;
+
+ /* Set register value */
+ val = AV8100_STANDBY_INTERRUPT_MASK_HPDM(hpdm) |
+ AV8100_STANDBY_INTERRUPT_MASK_CPDM(cpdm) |
+ AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG(stbygpiocfg) |
+ AV8100_STANDBY_INTERRUPT_MASK_IPOL(ipol);
+
+ /* Write to register */
+ retval = register_write_internal(AV8100_STANDBY_INTERRUPT_MASK, val);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
+
+int av8100_register_standby_pending_interrupt_write(
+ u8 hpdi, u8 cpdi, u8 oni)
+{
+ int retval;
+ u8 val;
+
+ LOCK_AV8100_HW;
+
+ /* Set register value */
+ val = AV8100_STANDBY_PENDING_INTERRUPT_HPDI(hpdi) |
+ AV8100_STANDBY_PENDING_INTERRUPT_CPDI(cpdi) |
+ AV8100_STANDBY_PENDING_INTERRUPT_ONI(oni);
+
+ /* Write to register */
+ retval = register_write_internal(AV8100_STANDBY_PENDING_INTERRUPT, val);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
+
+int av8100_register_general_interrupt_mask_write(
+ u8 eocm, u8 vsim, u8 vsom, u8 cecm, u8 hdcpm, u8 uovbm, u8 tem)
+{
+ int retval;
+ u8 val;
+
+ LOCK_AV8100_HW;
+
+ /* Set register value */
+ val = AV8100_GENERAL_INTERRUPT_MASK_EOCM(eocm) |
+ AV8100_GENERAL_INTERRUPT_MASK_VSIM(vsim) |
+ AV8100_GENERAL_INTERRUPT_MASK_VSOM(vsom) |
+ AV8100_GENERAL_INTERRUPT_MASK_CECM(cecm) |
+ AV8100_GENERAL_INTERRUPT_MASK_HDCPM(hdcpm) |
+ AV8100_GENERAL_INTERRUPT_MASK_UOVBM(uovbm) |
+ AV8100_GENERAL_INTERRUPT_MASK_TEM(tem);
+
+ /* Write to register */
+ retval = register_write_internal(AV8100_GENERAL_INTERRUPT_MASK, val);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
+
+int av8100_register_general_interrupt_write(
+ u8 eoci, u8 vsii, u8 vsoi, u8 ceci, u8 hdcpi, u8 uovbi)
+{
+ int retval;
+ u8 val;
+
+ LOCK_AV8100_HW;
+
+ /* Set register value */
+ val = AV8100_GENERAL_INTERRUPT_EOCI(eoci) |
+ AV8100_GENERAL_INTERRUPT_VSII(vsii) |
+ AV8100_GENERAL_INTERRUPT_VSOI(vsoi) |
+ AV8100_GENERAL_INTERRUPT_CECI(ceci) |
+ AV8100_GENERAL_INTERRUPT_HDCPI(hdcpi) |
+ AV8100_GENERAL_INTERRUPT_UOVBI(uovbi);
+
+ /* Write to register */
+ retval = register_write_internal(AV8100_GENERAL_INTERRUPT, val);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
+
+int av8100_register_gpio_configuration_write(
+ u8 dat3dir, u8 dat3val, u8 dat2dir, u8 dat2val, u8 dat1dir,
+ u8 dat1val, u8 ucdbg)
+{
+ int retval;
+ u8 val;
+
+ LOCK_AV8100_HW;
+
+ /* Set register value */
+ val = AV8100_GPIO_CONFIGURATION_DAT3DIR(dat3dir) |
+ AV8100_GPIO_CONFIGURATION_DAT3VAL(dat3val) |
+ AV8100_GPIO_CONFIGURATION_DAT2DIR(dat2dir) |
+ AV8100_GPIO_CONFIGURATION_DAT2VAL(dat2val) |
+ AV8100_GPIO_CONFIGURATION_DAT1DIR(dat1dir) |
+ AV8100_GPIO_CONFIGURATION_DAT1VAL(dat1val) |
+ AV8100_GPIO_CONFIGURATION_UCDBG(ucdbg);
+
+ /* Write to register */
+ retval = register_write_internal(AV8100_GPIO_CONFIGURATION, val);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
+
+int av8100_register_general_control_write(
+ u8 fdl, u8 hld, u8 wa, u8 ra)
+{
+ int retval;
+ u8 val;
+
+ LOCK_AV8100_HW;
+
+ /* Set register value */
+ val = AV8100_GENERAL_CONTROL_FDL(fdl) |
+ AV8100_GENERAL_CONTROL_HLD(hld) |
+ AV8100_GENERAL_CONTROL_WA(wa) |
+ AV8100_GENERAL_CONTROL_RA(ra);
+
+ /* Write to register */
+ retval = register_write_internal(AV8100_GENERAL_CONTROL, val);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
+
+int av8100_register_firmware_download_entry_write(
+ u8 mbyte_code_entry)
+{
+ int retval;
+ u8 val;
+
+ LOCK_AV8100_HW;
+
+ /* Set register value */
+ val = AV8100_FIRMWARE_DOWNLOAD_ENTRY_MBYTE_CODE_ENTRY(
+ mbyte_code_entry);
+
+ /* Write to register */
+ retval = register_write_internal(AV8100_FIRMWARE_DOWNLOAD_ENTRY, val);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
+
+int av8100_register_write(
+ u8 offset, u8 value)
+{
+ int retval = 0;
+ struct i2c_client *i2c;
+
+ LOCK_AV8100_HW;
+
+ if (!av8100_config) {
+ retval = AV8100_FAIL;
+ goto av8100_register_write_out;
}
- retval = av8100_read_single_byte(i2c, AV8100_5_VOLT_TIME_REG, &val);
- if(retval != AV8100_OK)
- {
- printk("Failed to read the value in to av8100 register\n");
- return -EFAULT;
- }else
- printk("AV8100_5_VOLT_TIME_REG register value:%0x\n",val);
+ i2c = av8100_config->client;
- retval = av8100_write_single_byte(i2c, GENERAL_CONTROL_REG, 0x30); /* Device in hold mode + enable firmware download*/
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to av8100 register\n");
- return -EFAULT;
+ /* Write to register */
+ retval = write_single_byte(i2c, offset, value);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to write the value to av8100 register\n");
+ retval = -EFAULT;
}
- retval = av8100_read_single_byte(i2c, GENERAL_CONTROL_REG, &val);
- if(retval != AV8100_OK)
- {
- printk("Failed to read the value in to av8100 register\n");
- return -EFAULT;
- }else
- printk("GENERAL_CONTROL_REG register value:%0x\n",val);
- av8100_set_state(AV8100_OPMODE_SCAN);
+av8100_register_write_out:
+ UNLOCK_AV8100_HW;
return retval;
}
-/**
- *
- * av8100_enable_interrupt() - This function will enable the hdmi/tvout plugin interrupts.
- * @i2c: i2c client device
- * @id: device id
- *
- **/
-static int av8100_enable_interrupt(struct i2c_client *i2c)
+int register_read_internal(u8 offset, u8 *value)
{
- int retval = AV8100_OK;
-#if defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI || \
- defined CONFIG_FB_U8500_MCDE_CHANNELC0_DISPLAY_HDMI|| \
- defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- char val = 0x0;
-#endif
+ int retval = 0;
+ struct i2c_client *i2c;
-#if defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI ||\
- defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- val = TE_INTERRUPT;
- retval = av8100_write_single_byte(i2c, GENERAL_INTERRUPT_MASK_REG, val);
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to av8100 register\n");
- return -EFAULT;
+ if (!av8100_config) {
+ retval = AV8100_FAIL;
+ goto av8100_register_read_out;
}
- val = 0x0;
- retval = av8100_write_single_byte(i2c, STANDBY_INTERRUPT_MASK_REG, val);
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to av8100 register\n");
- return -EFAULT;
- }
-#endif
+ i2c = av8100_config->client;
-#ifdef CONFIG_FB_U8500_MCDE_CHANNELC0_DISPLAY_HDMI
- val = 0x60;//0x60; // tearing & overflow/underflow interrupts
- retval = av8100_write_single_byte(i2c, GENERAL_INTERRUPT_MASK_REG, val);
- if(retval != AV8100_OK)
- {
- printk("Failed to write the value in to av8100 register\n");
- return -EFAULT;
+ /* Read from register */
+ retval = read_single_byte(i2c, offset, value);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to read the value from av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_register_read_out;
}
-#endif
+av8100_register_read_out:
return retval;
}
-/**
- * av8100_open() - This function will be used to open the av8100 device.
- * @inode: pointer to inode
- * @filp: pointer to file structure
- *
- **/
-static int av8100_open(struct inode *inode, struct file *filp)
+int av8100_register_standby_read(
+ u8 *cpd, u8 *stby, u8 *hpds, u8 *cpds, u8 *mclkrng)
{
- int retval = AV8100_OK;
- printk("av8100_open is called\n");
+ int retval;
+ u8 val;
+
+ LOCK_AV8100_HW;
+
+ /* Read from register */
+ retval = register_read_internal(AV8100_STANDBY, &val);
+
+ /* Set return params */
+ *cpd = AV8100_STANDBY_CPD_GET(val);
+ *stby = AV8100_STANDBY_STBY_GET(val);
+ *hpds = AV8100_STANDBY_HPDS_GET(val);
+ *cpds = AV8100_STANDBY_CPDS_GET(val);
+ *mclkrng = AV8100_STANDBY_MCLKRNG_GET(val);
+
+ UNLOCK_AV8100_HW;
return retval;
}
-/**
- * av8100_release() - This function will be used to close the av8100 device.
- * @inode: pointer to inode
- * @filp: pointer to file structure
- *
- **/
-static int av8100_release(struct inode *inode, struct file *filp)
+int av8100_register_hdmi_5_volt_time_read(
+ u8 *off_time, u8 *on_time)
{
- int retval = AV8100_OK;
- printk("av8100_release is called\n");
+ int retval;
+ u8 val;
+
+ LOCK_AV8100_HW;
+
+ /* Read from register */
+ retval = register_read_internal(AV8100_HDMI_5_VOLT_TIME, &val);
+
+ /* Set return params */
+ *off_time = AV8100_HDMI_5_VOLT_TIME_OFF_TIME_GET(val);
+ *on_time = AV8100_HDMI_5_VOLT_TIME_ON_TIME_GET(val);
+
+ UNLOCK_AV8100_HW;
return retval;
}
-/**
- * av8100_ioctl - This routine implements av8100 supported ioctls
- * @inode: inode pointer.
- * @file: file pointer.
- * @cmd : ioctl command.
- * @arg: input argument for ioctl.
- *
- * This Api supports the IOC_AV8100_READ_REGISTER,IOC_AV8100_WRITE_REGISTER,IOC_AV8100_SEND_CONFIGURATION_COMMAND
- * IOC_AV8100_READ_CONFIGURATION_COMMAND and IOC_AV8100_GET_STATUS ioctl commands.
- */
-static int av8100_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- int retval = AV8100_OK;
- struct av8100_register internalReg;
- struct av8100_command_register commandReg;
- struct av8100_status status;
- av8100_output_CEA_VESA video_output_format;
-#if defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI ||\
- defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- mcde_video_mode mcde_mode;
-#endif
- char val = 0x0;
-
- /** Process actual ioctl */
- switch(cmd)
- {
- case IOC_AV8100_READ_REGISTER:
- if(copy_from_user(&internalReg, (void *)arg, sizeof(struct av8100_register))) {
- return -EFAULT;
- }
+int av8100_register_standby_interrupt_mask_read(
+ u8 *hpdm, u8 *cpdm, u8 *stbygpiocfg, u8 *ipol)
+{
+ int retval;
+ u8 val;
- if (internalReg.offset <= FIRMWARE_DOWNLOAD_ENTRY_REG) {
- retval = av8100_read_single_byte(av8100Data->client, internalReg.offset, &internalReg.value);
+ LOCK_AV8100_HW;
- if(retval != AV8100_OK) {
- printk("Failed to read the value in to the av8100 register\n");
- return -EFAULT;
- }
- }
- else
- return AV8100_INVALID_COMMAND;
+ /* Read from register */
+ retval = register_read_internal(AV8100_STANDBY_INTERRUPT_MASK, &val);
- if (copy_to_user((void *)arg, (void *)&internalReg, sizeof(struct av8100_register))) {
- return -EFAULT;
- }
- break;
+ /* Set return params */
+ *hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_GET(val);
+ *cpdm = AV8100_STANDBY_INTERRUPT_MASK_CPDM_GET(val);
+ *stbygpiocfg = AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_GET(val);
+ *ipol = AV8100_STANDBY_INTERRUPT_MASK_IPOL_GET(val);
- case IOC_AV8100_WRITE_REGISTER:
- if(copy_from_user(&internalReg, (void *)arg, sizeof(struct av8100_register))) {
- return -EFAULT;
- }
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- if (internalReg.offset <= FIRMWARE_DOWNLOAD_ENTRY_REG) {
- retval = av8100_write_single_byte(av8100Data->client, internalReg.offset, internalReg.value);
- if(retval != AV8100_OK) {
- printk("Failed to write the value in to the av8100 register\n");
- return -EFAULT;
- }
- }
- else
- return AV8100_INVALID_COMMAND;
- //if(copy_to_user((void *)arg, (void *)&internalReg, sizeof(struct av8100_register))) {
- // return -EFAULT;
- //}
- break;
-
- case IOC_AV8100_SEND_CONFIGURATION_COMMAND:
- {
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_OK;
- val = 0x0;
+int av8100_register_standby_pending_interrupt_read(
+ u8 *hpdi, u8 *cpdi, u8 *oni, u8 *sid)
+{
+ int retval;
+ u8 val;
- if(copy_from_user(&commandReg, (void *)arg, sizeof(struct av8100_command_register)) != 0) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 1\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
+ LOCK_AV8100_HW;
- if(commandReg.return_status == HDMI_COMMAND_RETURN_STATUS_OK) {
- if(commandReg.cmd_id >= AV8100_COMMAND_VIDEO_INPUT_FORMAT && commandReg.cmd_id <= AV8100_COMMAND_PATTERNGENERATOR) {
- /* Writing the command buffer */
- retval = av8100_write_multi_byte(av8100Data->client, AV8100_COMMAND_OFFSET + 1, commandReg.buf, commandReg.buf_len);
- if(retval != AV8100_OK) {
- printk("Failed to send the command to the av8100\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- }
- else {
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- }
+ /* Read from register */
+ retval = register_read_internal(AV8100_STANDBY_PENDING_INTERRUPT, &val);
- if(commandReg.return_status == HDMI_COMMAND_RETURN_STATUS_OK) {
- /* Writing the command */
- retval = av8100_write_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET, commandReg.cmd_id);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 2\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- }
+ /* Set return params */
+ *hpdi = AV8100_STANDBY_PENDING_INTERRUPT_HPDI_GET(val);
+ *cpdi = AV8100_STANDBY_PENDING_INTERRUPT_CPDI_GET(val);
+ *oni = AV8100_STANDBY_PENDING_INTERRUPT_ONI_GET(val);
+ *sid = AV8100_STANDBY_PENDING_INTERRUPT_SID_GET(val);
- /* TODO */
- mdelay(100);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- if(commandReg.return_status == HDMI_COMMAND_RETURN_STATUS_OK) {
- /* Getting the first return byte */
- retval = av8100_read_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET, &val);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 3\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- else {
- /* Checking the first return byte */
- if(val != (0x80 | commandReg.cmd_id)) { //offset 0x10 == 0x80 | Identifier
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 4 %0x\n", val);
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- }
- }
+int av8100_register_general_interrupt_mask_read(
+ u8 *eocm,
+ u8 *vsim,
+ u8 *vsom,
+ u8 *cecm,
+ u8 *hdcpm,
+ u8 *uovbm,
+ u8 *tem)
+{
+ int retval;
+ u8 val;
- commandReg.buf_len = 0;
-
- switch(commandReg.cmd_id) {
- case AV8100_COMMAND_VIDEO_INPUT_FORMAT:
- case AV8100_COMMAND_AUDIO_INPUT_FORMAT:
- case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT:
- case AV8100_COMMAND_VIDEO_SCALING_FORMAT:
- case AV8100_COMMAND_COLORSPACECONVERSION:
- case AV8100_COMMAND_CEC_MESSAGEWRITE:
- case AV8100_COMMAND_DENC:
- case AV8100_COMMAND_HDMI:
- case AV8100_COMMAND_HDCP_SENDKEY:
- case AV8100_COMMAND_INFOFRAMES:
- case AV8100_COMMAND_PATTERNGENERATOR:
- if(commandReg.return_status == HDMI_COMMAND_RETURN_STATUS_OK) {
- /* Getting the second return byte */
- retval = av8100_read_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET + 1, &val);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 5\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- else {
- /* Checking the second return byte */
- if (val != AV8100_OK) {
- printk("Invalid Response for the command %0x\n", val);
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- }
- }
- break;
+ LOCK_AV8100_HW;
- case AV8100_COMMAND_CEC_MESSAGEREAD_BACK:
- if(commandReg.return_status == HDMI_COMMAND_RETURN_STATUS_OK) {
+ /* Read from register */
+ retval = register_read_internal(AV8100_GENERAL_INTERRUPT_MASK, &val);
-#if 0
- retval = av8100_read_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET + 1, &val);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 6a\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- else {
- printk("AV8100_COMMAND_OFFSET + 1:%x\n", val);
- }
+ /* Set return params */
+ *eocm = AV8100_GENERAL_INTERRUPT_MASK_EOCM_GET(val);
+ *vsim = AV8100_GENERAL_INTERRUPT_MASK_VSIM_GET(val);
+ *vsom = AV8100_GENERAL_INTERRUPT_MASK_VSOM_GET(val);
+ *cecm = AV8100_GENERAL_INTERRUPT_MASK_CECM_GET(val);
+ *hdcpm = AV8100_GENERAL_INTERRUPT_MASK_HDCPM_GET(val);
+ *uovbm = AV8100_GENERAL_INTERRUPT_MASK_UOVBM_GET(val);
+ *tem = AV8100_GENERAL_INTERRUPT_MASK_TEM_GET(val);
- retval = av8100_read_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET + 2, &val);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 6b\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- else {
- printk("AV8100_COMMAND_OFFSET + 2:%x\n", val);
- }
-#endif
- /* Getting the buffer length */
- retval = av8100_read_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET + 3, &val);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 6\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- else {
- commandReg.buf_len = val;
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- if (commandReg.buf_len > HDMI_CEC_MESSAGE_READBACK_MAXSIZE) {
- printk("AV8100_COMMAND_CEC_MESSAGEREAD_BACK buf_len: %d larger than maxsize\n", commandReg.buf_len);
- commandReg.buf_len = 16;
- }
- }
- }
+int av8100_register_general_interrupt_read(
+ u8 *eoci,
+ u8 *vsii,
+ u8 *vsoi,
+ u8 *ceci,
+ u8 *hdcpi,
+ u8 *uovbi,
+ u8 *tei)
+{
+ int retval;
+ u8 val;
- if(commandReg.return_status == HDMI_COMMAND_RETURN_STATUS_OK) {
- int index = 0;
-
- /* Getting the buffer */
- while ((index < commandReg.buf_len) && (index < HDMI_CEC_MESSAGE_READBACK_MAXSIZE)) {
- retval = av8100_read_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET + 4 + index, &val);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 7\n");
- commandReg.buf_len = 0;
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- break;
- }
- else {
- commandReg.buf[index] = val;
- }
-
- index++;
- }
- }
- break;
+ LOCK_AV8100_HW;
- case AV8100_COMMAND_HDCP_MANAGEMENT:
- if(commandReg.return_status == HDMI_COMMAND_RETURN_STATUS_OK) {
+ /* Read from register */
+ retval = register_read_internal(AV8100_GENERAL_INTERRUPT, &val);
- /* Getting the second return byte */
- retval = av8100_read_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET + 1, &val);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 5\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- else {
- /* Checking the second return byte */
- if (val != AV8100_OK) {
- printk("Invalid Response for the command\n");
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- }
- }
- }
+ /* Set return params */
+ *eoci = AV8100_GENERAL_INTERRUPT_EOCI_GET(val);
+ *vsii = AV8100_GENERAL_INTERRUPT_VSII_GET(val);
+ *vsoi = AV8100_GENERAL_INTERRUPT_VSOI_GET(val);
+ *ceci = AV8100_GENERAL_INTERRUPT_CECI_GET(val);
+ *hdcpi = AV8100_GENERAL_INTERRUPT_HDCPI_GET(val);
+ *uovbi = AV8100_GENERAL_INTERRUPT_UOVBI_GET(val);
+ *tei = AV8100_GENERAL_INTERRUPT_TEI_GET(val);
- if(commandReg.return_status == HDMI_COMMAND_RETURN_STATUS_OK) {
- int index = 0;
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- /* Getting the buffer length */
- if(commandReg.buf[0] == HDMI_REQUEST_FOR_REVOCATION_LIST_INPUT) {
- commandReg.buf_len = 0x1F;
- }
- else {
- commandReg.buf_len = 0x0;
- }
+int av8100_register_general_status_read(
+ u8 *cecrec,
+ u8 *cectrx,
+ u8 *uc,
+ u8 *onuvb,
+ u8 *hdcps)
+{
+ int retval;
+ u8 val;
- /* Getting the buffer */
- while (index < commandReg.buf_len) {
- retval = av8100_read_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET + 2 + index, &val);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 8\n");
- commandReg.buf_len = 0;
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- break;
- }
- else {
- commandReg.buf[index] = val;
- }
-
- index++;
- }
- }
- break;
-
- case AV8100_COMMAND_EDID_SECTIONREADBACK:
- if(commandReg.return_status == HDMI_COMMAND_RETURN_STATUS_OK) {
- int index = 0;
-
- commandReg.buf_len = 0x80;
-
- /* Getting the buffer */
- while (index < commandReg.buf_len) {
- retval = av8100_read_single_byte(av8100Data->client, AV8100_COMMAND_OFFSET + 1 + index, &val);
- if(retval != AV8100_OK) {
- printk("IOC_AV8100_SEND_CONFIGURATION_COMMAND fail 9\n");
- commandReg.buf_len = 0;
- commandReg.return_status = HDMI_COMMAND_RETURN_STATUS_FAIL;
- break;
- }
- else {
- commandReg.buf[index] = val;
- }
-
- index++;
- }
- }
- break;
- }
+ LOCK_AV8100_HW;
- if(copy_to_user((void *)arg, (void *)&commandReg, sizeof(struct av8100_command_register)) != 0) {
- return -EFAULT;
- }
- }
- break;
-#if 0
- case IOC_AV8100_READ_CONFIGURATION_COMMAND:
- if(copy_from_user(&commandReg, (void *)arg, sizeof(struct av8100_command_register))) {
- return -EFAULT;
- }
+ /* Read from register */
+ retval = register_read_internal(AV8100_GENERAL_STATUS, &val);
- if(copy_to_user((void *)arg, (void *)&commandReg, sizeof(struct av8100_command_register))) {
- return -EFAULT;
- }
- break;
-#endif
- case IOC_AV8100_GET_STATUS:
- {
- char val = 0;
+ /* Set return params */
+ *cecrec = AV8100_GENERAL_STATUS_CECREC_GET(val);
+ *cectrx = AV8100_GENERAL_STATUS_CECTRX_GET(val);
+ *uc = AV8100_GENERAL_STATUS_UC_GET(val);
+ *onuvb = AV8100_GENERAL_STATUS_ONUVB_GET(val);
+ *hdcps = AV8100_GENERAL_STATUS_HDCPS_GET(val);
- status.av8100_state = av8100_get_state();
- status.av8100_plugin_status = 0;
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- if(status.av8100_state != AV8100_OPMODE_SHUTDOWN) {
- retval = av8100_read_single_byte(av8100Data->client, STANDBY_REG, &val);
- if(retval != AV8100_OK)
- {
- printk("Failed to read the value in to av8100 register\n");
- return -EFAULT;
- }
+int av8100_register_gpio_configuration_read(
+ u8 *dat3dir,
+ u8 *dat3val,
+ u8 *dat2dir,
+ u8 *dat2val,
+ u8 *dat1dir,
+ u8 *dat1val,
+ u8 *ucdbg)
+{
+ int retval;
+ u8 val;
- status.av8100_plugin_status = AV8100_PLUGIN_NONE;
- if(val & STANDBY_HPDS_HDMI_PLUGGED) {
- status.av8100_plugin_status |= AV8100_HDMI_PLUGIN;
- }
+ LOCK_AV8100_HW;
- if(val & STANDBY_CVBS_TV_CABLE_PLUGGED) {
- status.av8100_plugin_status |= AV8100_CVBS_PLUGIN;
- }
- }
+ /* Read from register */
+ retval = register_read_internal(AV8100_GPIO_CONFIGURATION, &val);
- printk("av8100_state:%0x av8100_plugin_status:%0x\n", status.av8100_state, status.av8100_plugin_status);
+ /* Set return params */
+ *dat3dir = AV8100_GPIO_CONFIGURATION_DAT3DIR_GET(val);
+ *dat3val = AV8100_GPIO_CONFIGURATION_DAT3VAL_GET(val);
+ *dat2dir = AV8100_GPIO_CONFIGURATION_DAT2DIR_GET(val);
+ *dat2val = AV8100_GPIO_CONFIGURATION_DAT2VAL_GET(val);
+ *dat1dir = AV8100_GPIO_CONFIGURATION_DAT1DIR_GET(val);
+ *dat1val = AV8100_GPIO_CONFIGURATION_DAT1VAL_GET(val);
+ *ucdbg = AV8100_GPIO_CONFIGURATION_UCDBG_GET(val);
- if(copy_to_user((void *)arg, (void *)&status, sizeof(struct av8100_status))) {
- return -EFAULT;
- }
- }
- break;
-
- case IOC_AV8100_ENABLE:
- /* Use the latest video mode */
-#if defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI ||\
- defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- mcde_mode = av8100_get_mcde_video_mode(hdmi_video_output_cmd.video_output_cea_vesa);
- mcde_hdmi_display_init_command_mode(mcde_mode);
-#endif
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- retval = av8100_powerup(av8100Data->client, 0);
- if(retval != AV8100_OK){
- printk("error in av8100_powerup\n");
- break;
- }
+int av8100_register_general_control_read(
+ u8 *fdl,
+ u8 *hld,
+ u8 *wa,
+ u8 *ra)
+{
+ int retval;
+ u8 val;
- g_av8100_state = AV8100_OPMODE_INIT;
+ LOCK_AV8100_HW;
- retval = av8100_download_firmware(av8100Data->client, FIRMWARE_DOWNLOAD_ENTRY_REG, av8100_fw_buff, fw_size, I2C_INTERFACE);
- if(retval != AV8100_OK){
- printk("error in av8100_download_firmware\n");
- break;
- }
+ /* Read from register */
+ retval = register_read_internal(AV8100_GENERAL_CONTROL, &val);
+ /* Set return params */
+ *fdl = AV8100_GENERAL_CONTROL_FDL_GET(val);
+ *hld = AV8100_GENERAL_CONTROL_HLD_GET(val);
+ *wa = AV8100_GENERAL_CONTROL_WA_GET(val);
+ *ra = AV8100_GENERAL_CONTROL_RA_GET(val);
- av8100_configure_hdmi(av8100Data->client);
-
- retval = av8100_enable_interrupt(av8100Data->client);
- if(retval != AV8100_OK){
- printk("error in av8100_enable_interrupt\n");
- break;
- }
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- av8100_hdmi_on(av8100Data);
- break;
+int av8100_register_firmware_download_entry_read(
+ u8 *mbyte_code_entry)
+{
+ int retval;
+ u8 val;
- case IOC_AV8100_DISABLE:
- av8100_hdmi_off(av8100Data);
- av8100_powerdown();
- break;
+ LOCK_AV8100_HW;
- case IOC_AV8100_SET_VIDEO_FORMAT:
- printk(KERN_INFO "IOC_AV8100_SET_VIDEO_FORMAT\n");
+ /* Read from register */
+ retval = register_read_internal(AV8100_FIRMWARE_DOWNLOAD_ENTRY, &val);
- if(copy_from_user(&video_output_format, (void *)arg, sizeof(av8100_output_CEA_VESA))) {
- return -EFAULT;
- }
+ /* Set return params */
+ *mbyte_code_entry =
+ AV8100_FIRMWARE_DOWNLOAD_ENTRY_MBYTE_CODE_ENTRY_GET(val);
- if (video_output_format < AV8100_VIDEO_OUTPUT_CEA_VESA_MAX) {
- /* hdmi_off */
- av8100_hdmi_off(av8100Data);
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- /* powerdown */
- av8100_powerdown();
+int av8100_register_read(
+ u8 offset,
+ u8 *value)
+{
+ int retval = 0;
+ struct i2c_client *i2c;
- /* mcde */
- hdmi_video_output_cmd.video_output_cea_vesa = video_output_format;
- av8100_config_output_dep_params();
-#if defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI ||\
- defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- mcde_mode = av8100_get_mcde_video_mode(video_output_format);
- mcde_hdmi_display_init_command_mode(mcde_mode);
-#endif
+ LOCK_AV8100_HW;
- /* powerup */
- retval = av8100_powerup(av8100Data->client, 0);
- if(retval != AV8100_OK){
- printk("error in av8100_powerup\n");
- break;
- }
+ if (!av8100_config) {
+ retval = AV8100_FAIL;
+ goto av8100_register_read_out;
+ }
- g_av8100_state = AV8100_OPMODE_INIT;
+ i2c = av8100_config->client;
- /* download fw */
- retval = av8100_download_firmware(av8100Data->client, FIRMWARE_DOWNLOAD_ENTRY_REG, av8100_fw_buff, fw_size, I2C_INTERFACE);
- if(retval != AV8100_OK){
- printk("error in av8100_download_firmware\n");
- break;
- }
+ /* Read from register */
+ retval = read_single_byte(i2c, offset, value);
+ if (retval) {
+ printk(KERN_DEBUG "Failed to read the value from av8100 register\n");
+ retval = -EFAULT;
+ goto av8100_register_read_out;
+ }
- hdmi_video_input_cmd.TE_line_nb = av8100_get_te_line_nb(video_output_format);
- hdmi_video_input_cmd.ui_x4 = av8100_get_ui_x4(video_output_format);
+av8100_register_read_out:
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- /* configure hdmi */
- av8100_configure_hdmi(av8100Data->client);
+int av8100_configuration_get(enum av8100_command_type command_type,
+ union av8100_configuration *config)
+{
+ if (!av8100_config || !config)
+ return AV8100_FAIL;
+
+ /* Put configuration data to the corresponding data struct depending
+ * on command type */
+ switch (command_type) {
+ case AV8100_COMMAND_VIDEO_INPUT_FORMAT:
+ memcpy(&config->video_input_format,
+ &av8100_config->hdmi_video_input_cmd,
+ sizeof(struct av8100_video_input_format_cmd));
+ break;
- /* enable int */
- retval = av8100_enable_interrupt(av8100Data->client);
- if(retval != AV8100_OK){
- printk("error in av8100_enable_interrupt\n");
- break;
- }
+ case AV8100_COMMAND_AUDIO_INPUT_FORMAT:
+ memcpy(&config->audio_input_format,
+ &av8100_config->hdmi_audio_input_cmd,
+ sizeof(struct av8100_audio_input_format_cmd));
+ break;
- /* hdmi on */
- av8100_hdmi_on(av8100Data);
- }
- else {
- retval = AV8100_INVALID_COMMAND;
- }
+ case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT:
+ memcpy(&config->video_output_format,
+ &av8100_config->hdmi_video_output_cmd,
+ sizeof(struct av8100_video_output_format_cmd));
break;
-#if 1
-//Test
- case IOC_AV8100_HDMI_ON:
- printk(KERN_INFO "IOC_AV8100_HDMI_ON\n");
- av8100_hdmi_on(av8100Data);
+ case AV8100_COMMAND_VIDEO_SCALING_FORMAT:
+ memcpy(&config->video_scaling_format,
+ &av8100_config->hdmi_video_scaling_cmd,
+ sizeof(struct av8100_video_scaling_format_cmd));
break;
- case IOC_AV8100_HDMI_OFF:
- printk(KERN_INFO "IOC_AV8100_HDMI_OFF\n");
- av8100_hdmi_off(av8100Data);
+ case AV8100_COMMAND_COLORSPACECONVERSION:
+ memcpy(&config->color_space_conversion_format,
+ &av8100_config->hdmi_color_space_conversion_cmd,
+ sizeof(struct
+ av8100_color_space_conversion_format_cmd));
break;
-#endif
- default:
- return AV8100_INVALID_IOCTL;
- }
- return retval;
-}
+ case AV8100_COMMAND_CEC_MESSAGE_WRITE:
+ memcpy(&config->cec_message_write_format,
+ &av8100_config->hdmi_cec_message_write_cmd,
+ sizeof(struct av8100_cec_message_write_format_cmd));
+ break;
-static unsigned short av8100_get_te_line_nb(av8100_output_CEA_VESA output_video_format)
-{
- unsigned short retval;
+ case AV8100_COMMAND_CEC_MESSAGE_READ_BACK:
+ memcpy(&config->cec_message_read_back_format,
+ &av8100_config->hdmi_cec_message_read_back_cmd,
+ sizeof(struct av8100_cec_message_read_back_format_cmd));
+ break;
- switch(output_video_format) {
- case AV8100_CEA1_640X480P_59_94HZ:
- case AV8100_CEA2_3_720X480P_59_94HZ:
- retval = 30;
+ case AV8100_COMMAND_DENC:
+ memcpy(&config->denc_format, &av8100_config->hdmi_denc_cmd,
+ sizeof(struct av8100_denc_format_cmd));
break;
- case AV8100_CEA5_1920X1080I_60HZ:
- case AV8100_CEA6_7_NTSC_60HZ:
- case AV8100_CEA20_1920X1080I_50HZ:
- retval = 18;
+ case AV8100_COMMAND_HDMI:
+ memcpy(&config->hdmi_format, &av8100_config->hdmi_cmd,
+ sizeof(struct av8100_hdmi_cmd));
break;
- case AV8100_CEA4_1280X720P_60HZ:
- retval = 21;
+ case AV8100_COMMAND_HDCP_SENDKEY:
+ memcpy(&config->hdcp_send_key_format,
+ &av8100_config->hdmi_hdcp_send_key_cmd,
+ sizeof(struct av8100_hdcp_send_key_format_cmd));
break;
- case AV8100_CEA17_18_720X576P_50HZ:
- retval = 40;
+ case AV8100_COMMAND_HDCP_MANAGEMENT:
+ memcpy(&config->hdcp_management_format,
+ &av8100_config->hdmi_hdcp_management_format_cmd,
+ sizeof(struct av8100_hdcp_management_format_cmd));
break;
- case AV8100_CEA19_1280X720P_50HZ:
- retval = 22;
+ case AV8100_COMMAND_INFOFRAMES:
+ memcpy(&config->infoframes_format,
+ &av8100_config->hdmi_infoframes_cmd,
+ sizeof(struct av8100_infoframes_format_cmd));
break;
- case AV8100_CEA21_22_576I_PAL_50HZ:
- /* Different values below come from LLD,
- * TODO: check if this is really needed
- * if not merge with AV8100_CEA6_7_NTSC_60HZ case
- */
-#ifdef CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- retval = 18;
-#else
- retval = 17;
-#endif
+ case AV8100_COMMAND_EDID_SECTION_READBACK:
+ memcpy(&config->edid_section_readback_format,
+ &av8100_config->hdmi_edid_section_readback_cmd,
+ sizeof(struct
+ av8100_edid_section_readback_format_cmd));
break;
- case AV8100_CEA32_1920X1080P_24HZ:
- case AV8100_CEA33_1920X1080P_25HZ:
- case AV8100_CEA34_1920X1080P_30HZ:
- retval = 38;
+ case AV8100_COMMAND_PATTERNGENERATOR:
+ memcpy(&config->pattern_generator_format,
+ &av8100_config->hdmi_pattern_generator_cmd,
+ sizeof(struct av8100_pattern_generator_format_cmd));
break;
- case AV8100_CEA60_1280X720P_24HZ:
- case AV8100_CEA62_1280X720P_30HZ:
- retval = 21;
+ case AV8100_COMMAND_FUSE_AES_KEY:
+ memcpy(&config->fuse_aes_key_format,
+ &av8100_config->hdmi_fuse_aes_key_cmd,
+ sizeof(struct av8100_fuse_aes_key_format_cmd));
break;
- case AV8100_CEA14_15_480p_60HZ:
- case AV8100_VESA14_848X480P_60HZ:
- case AV8100_CEA61_1280X720P_25HZ:
- case AV8100_CEA16_1920X1080P_60HZ:
- case AV8100_CEA31_1920x1080P_50Hz:
- case AV8100_CEA29_30_576P_50HZ:
- case AV8100_VESA9_800X600P_60_32HZ:
- case AV8100_VESA16_1024X768P_60HZ:
- case AV8100_VESA22_1280X768P_59_99HZ:
- case AV8100_VESA23_1280X768P_59_87HZ:
- case AV8100_VESA27_1280X800P_59_91HZ:
- case AV8100_VESA28_1280X800P_59_81HZ:
- case AV8100_VESA39_1360X768P_60_02HZ:
- case AV8100_VESA81_1366X768P_59_79HZ:
default:
- /* TODO */
- retval = 14;
+ return AV8100_FAIL;
break;
}
- return retval;
+ return 0;
}
-static unsigned short av8100_get_ui_x4(av8100_output_CEA_VESA output_video_format)
+int av8100_configuration_prepare(enum av8100_command_type command_type,
+ union av8100_configuration *config)
{
- unsigned short retval = 6;
+ if (!av8100_config || !config)
+ return AV8100_FAIL;
+
+ /* Put configuration data to the corresponding data struct depending
+ * on command type */
+ switch (command_type) {
+ case AV8100_COMMAND_VIDEO_INPUT_FORMAT:
+ memcpy(&av8100_config->hdmi_video_input_cmd,
+ &config->video_input_format,
+ sizeof(struct av8100_video_input_format_cmd));
+ break;
- switch(output_video_format) {
- case AV8100_CEA1_640X480P_59_94HZ:
- case AV8100_CEA2_3_720X480P_59_94HZ:
- case AV8100_CEA4_1280X720P_60HZ:
- case AV8100_CEA5_1920X1080I_60HZ:
- case AV8100_CEA6_7_NTSC_60HZ:
- case AV8100_CEA17_18_720X576P_50HZ:
- case AV8100_CEA19_1280X720P_50HZ:
- case AV8100_CEA20_1920X1080I_50HZ:
- case AV8100_CEA21_22_576I_PAL_50HZ:
- case AV8100_CEA32_1920X1080P_24HZ:
- case AV8100_CEA33_1920X1080P_25HZ:
- case AV8100_CEA34_1920X1080P_30HZ:
- case AV8100_CEA60_1280X720P_24HZ:
- case AV8100_CEA62_1280X720P_30HZ:
- retval = 6;
+ case AV8100_COMMAND_AUDIO_INPUT_FORMAT:
+ memcpy(&av8100_config->hdmi_audio_input_cmd,
+ &config->audio_input_format,
+ sizeof(struct av8100_audio_input_format_cmd));
break;
- case AV8100_CEA14_15_480p_60HZ:
- case AV8100_VESA14_848X480P_60HZ:
- case AV8100_CEA61_1280X720P_25HZ:
- case AV8100_CEA16_1920X1080P_60HZ:
- case AV8100_CEA31_1920x1080P_50Hz:
- case AV8100_CEA29_30_576P_50HZ:
- case AV8100_VESA9_800X600P_60_32HZ:
- case AV8100_VESA16_1024X768P_60HZ:
- case AV8100_VESA22_1280X768P_59_99HZ:
- case AV8100_VESA23_1280X768P_59_87HZ:
- case AV8100_VESA27_1280X800P_59_91HZ:
- case AV8100_VESA28_1280X800P_59_81HZ:
- case AV8100_VESA39_1360X768P_60_02HZ:
- case AV8100_VESA81_1366X768P_59_79HZ:
- default:
- /* TODO */
- retval = 6;
+ case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT:
+ memcpy(&av8100_config->hdmi_video_output_cmd,
+ &config->video_output_format,
+ sizeof(struct av8100_video_output_format_cmd));
+
+ /* Set params that depend on video output */
+ av8100_config_video_output_dep(av8100_config->
+ hdmi_video_output_cmd.video_output_cea_vesa);
break;
- }
- return retval;
-}
+ case AV8100_COMMAND_VIDEO_SCALING_FORMAT:
+ memcpy(&av8100_config->hdmi_video_scaling_cmd,
+ &config->video_scaling_format,
+ sizeof(struct av8100_video_scaling_format_cmd));
+ break;
-static void av8100_init_config_params(void)
-{
- memset(&hdmi_video_output_cmd, 0x0, sizeof(av8100_video_output_format_cmd));
+ case AV8100_COMMAND_COLORSPACECONVERSION:
+ memcpy(&av8100_config->hdmi_color_space_conversion_cmd,
+ &config->color_space_conversion_format,
+ sizeof(struct
+ av8100_color_space_conversion_format_cmd));
+ break;
+ case AV8100_COMMAND_CEC_MESSAGE_WRITE:
+ memcpy(&av8100_config->hdmi_cec_message_write_cmd,
+ &config->cec_message_write_format,
+ sizeof(struct av8100_cec_message_write_format_cmd));
+ break;
- /* SDTV mode settings */
-#ifdef CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
+ case AV8100_COMMAND_CEC_MESSAGE_READ_BACK:
+ memcpy(&av8100_config->hdmi_cec_message_read_back_cmd,
+ &config->cec_message_read_back_format,
+ sizeof(struct av8100_cec_message_read_back_format_cmd));
+ break;
- /* Default output mode */
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA21_22_576I_PAL_50HZ;
-#ifdef CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_PAL_THRU_AV8100
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA21_22_576I_PAL_50HZ;
-#elif defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_NTSC_THRU_AV8100
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA6_7_NTSC_60HZ;
-#endif
+ case AV8100_COMMAND_DENC:
+ memcpy(&av8100_config->hdmi_denc_cmd, &config->denc_format,
+ sizeof(struct av8100_denc_format_cmd));
+ break;
- hdmi_color_conversion_cmd.c0 = 0xFFDA;
- hdmi_color_conversion_cmd.c1 = 0xFFB6;
- hdmi_color_conversion_cmd.c2 = 0x0070;
- hdmi_color_conversion_cmd.c3 = 0x0042;
- hdmi_color_conversion_cmd.c4 = 0x0081;
- hdmi_color_conversion_cmd.c5 = 0x0019;
- hdmi_color_conversion_cmd.c6 = 0x0070;
- hdmi_color_conversion_cmd.c7 = 0xFFA2;
- hdmi_color_conversion_cmd.c8 = 0xFFEE;
- hdmi_color_conversion_cmd.a_offset = 0x007F;
- hdmi_color_conversion_cmd.b_offset = 0x0010;
- hdmi_color_conversion_cmd.c_offset = 0x007F;
- hdmi_color_conversion_cmd.l_max = 0xEB;
- hdmi_color_conversion_cmd.l_min = 0x10;
- hdmi_color_conversion_cmd.c_max = 0xF0;
- hdmi_color_conversion_cmd.c_min = 0x10;
-
-#else /* CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV */
-
- /* Default output mode */
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA4_1280X720P_60HZ;
-
- /* HDMI mode settings */
-#ifdef CONFIG_FB_U8500_MCDE_HDMI_640x480P60
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA1_640X480P_59_94HZ;
-#endif
-#ifdef CONFIG_FB_U8500_MCDE_HDMI_720x480P60
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA2_3_720X480P_59_94HZ;
-#endif
-#ifdef CONFIG_FB_U8500_MCDE_HDMI_1280x720P60
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA4_1280X720P_60HZ;
-#endif
-#ifdef CONFIG_FB_U8500_MCDE_HDMI_1920x1080I60
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA5_1920X1080I_60HZ;
-#endif
-#ifdef CONFIG_FB_U8500_MCDE_HDMI_1920x1080I50
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA20_1920X1080I_50HZ;
-#endif
-#ifdef CONFIG_FB_U8500_MCDE_HDMI_1920x1080P30
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA34_1920X1080P_30HZ;
-#endif
-#ifdef CONFIG_FB_U8500_MCDE_HDMI_720x576I50
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA21_22_576I_PAL_50HZ;
-#endif
-#ifdef CONFIG_FB_U8500_MCDE_HDMI_720x480I60
- hdmi_video_output_cmd.video_output_cea_vesa = AV8100_CEA6_7_NTSC_60HZ;
-#endif
-#endif /* else of if CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV */
- av8100_config_output_dep_params();
-}
-
-static void av8100_config_output_dep_params(void)
-{
- memset(&hdmi_cmd, 0x0, sizeof(av8100_hdmi_cmd));
- memset(&hdmi_video_input_cmd, 0x0, sizeof(av8100_video_input_format_cmd));
- memset(&hdmi_pattern_generator_cmd, 0x0, sizeof(av8100_pattern_generator_cmd));
- memset(&hdmi_audio_input_cmd, 0x0, sizeof(av8100_audio_input_format_cmd));
- memset(&hdmi_denc_cmd, 0x0, sizeof(av8100_denc_cmd));
-
- hdmi_video_input_cmd.dsi_input_mode = AV8100_HDMI_DSI_COMMAND_MODE;
- hdmi_video_input_cmd.total_horizontal_pixel = av8100_all_cea[
- hdmi_video_output_cmd.video_output_cea_vesa].htotale;
- hdmi_video_input_cmd.total_horizontal_active_pixel = av8100_all_cea[
- hdmi_video_output_cmd.video_output_cea_vesa].hactive;
- hdmi_video_input_cmd.total_vertical_lines = av8100_all_cea[
- hdmi_video_output_cmd.video_output_cea_vesa].vtotale;
- hdmi_video_input_cmd.total_vertical_active_lines = av8100_all_cea[
- hdmi_video_output_cmd.video_output_cea_vesa].vactive;
-
- hdmi_video_input_cmd.nb_data_lane = AV8100_DATA_LANES_USED_2;
-#ifdef CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- /* hdmi_video_input_cmd.input_pixel_format = AV8100_INPUT_PIX_YCBCR422;
- */
- hdmi_video_input_cmd.input_pixel_format = AV8100_INPUT_PIX_RGB565;
- hdmi_video_input_cmd.video_mode = AV8100_VIDEO_INTERLACE;
-
- /* only shared for channel A */
- hdmi_video_input_cmd.ui_x4 = av8100_get_ui_x4(
- hdmi_video_output_cmd.video_output_cea_vesa);
- hdmi_video_input_cmd.TE_config = AV8100_TE_IT_LINE;
- hdmi_video_input_cmd.TE_line_nb = av8100_get_te_line_nb(
- hdmi_video_output_cmd.video_output_cea_vesa);
-
- if (hdmi_video_output_cmd.video_output_cea_vesa ==
- AV8100_CEA21_22_576I_PAL_50HZ
- ) {
- hdmi_denc_cmd.tv_lines = AV8100_TV_LINES_625;
- hdmi_denc_cmd.tv_std = AV8100_TV_STD_PALBDGHI;
- } else if (
- hdmi_video_output_cmd.video_output_cea_vesa ==
- AV8100_CEA6_7_NTSC_60HZ
- ) {
- hdmi_denc_cmd.tv_lines = AV8100_TV_LINES_525;
- hdmi_denc_cmd.tv_std = AV8100_TV_STD_NTSCM;
- } else {
- printk(KERN_WARNING "AV8100: unsupported video mode, using default\n");
- hdmi_denc_cmd.tv_lines = AV8100_TV_LINES_625;
- }
- hdmi_denc_cmd.denc = AV8100_DENC_ON;
- hdmi_denc_cmd.macrovision = AV8100_MACROVISION_OFF;
+ case AV8100_COMMAND_HDMI:
+ memcpy(&av8100_config->hdmi_cmd, &config->hdmi_format,
+ sizeof(struct av8100_hdmi_cmd));
+ break;
-#ifdef TEST_PATTERN_TEST
- hdmi_denc_cmd.internal_generator = AV8100_INTERNAL_GENERATOR_ON;
- hdmi_denc_cmd.chroma = AV8100_CHROMA_CWS_CAPTURE_ON;
-#else
- hdmi_denc_cmd.internal_generator = AV8100_INTERNAL_GENERATOR_OFF;
- hdmi_denc_cmd.chroma = AV8100_CHROMA_CWS_CAPTURE_OFF;
-#endif /* CONFIG_AV8100_TEST_PATTERN */
-
-#else /* CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV */
-
- /** Config for command mode **/
-#ifdef CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI
- hdmi_video_input_cmd.ui_x4 = av8100_get_ui_x4(hdmi_video_output_cmd.video_output_cea_vesa);
- hdmi_video_input_cmd.TE_line_nb = av8100_get_te_line_nb(hdmi_video_output_cmd.video_output_cea_vesa);
- // hdmi_video_input_cmd.TE_config = AV8100_TE_DSI_IT; // IT on both I/F (DSI & GPIO)
- hdmi_video_input_cmd.TE_config = AV8100_TE_IT_LINE; // IT on both I/F (DSI & GPIO)
-#endif
+ case AV8100_COMMAND_HDCP_SENDKEY:
+ memcpy(&av8100_config->hdmi_hdcp_send_key_cmd,
+ &config->hdcp_send_key_format,
+ sizeof(struct av8100_hdcp_send_key_format_cmd));
+ break;
-#ifdef CONFIG_FB_U8500_MCDE_CHANNELC0_DISPLAY_HDMI
- /** Config for video mode **/
- hdmi_video_input_cmd.dsi_input_mode = AV8100_HDMI_DSI_VIDEO_MODE;
- hdmi_video_input_cmd.TE_line_nb = 0;
- hdmi_video_input_cmd.TE_config = AV8100_TE_OFF; // No TE IT
-#endif
+ case AV8100_COMMAND_HDCP_MANAGEMENT:
+ memcpy(&av8100_config->hdmi_hdcp_management_format_cmd,
+ &config->hdcp_management_format,
+ sizeof(struct av8100_hdcp_management_format_cmd));
+ break;
- hdmi_video_input_cmd.input_pixel_format = AV8100_INPUT_PIX_RGB565;
- if (hdmi_video_output_cmd.video_output_cea_vesa ==
- AV8100_CEA5_1920X1080I_60HZ
- ||
- hdmi_video_output_cmd.video_output_cea_vesa ==
- AV8100_CEA20_1920X1080I_50HZ
- ||
- hdmi_video_output_cmd.video_output_cea_vesa ==
- AV8100_CEA21_22_576I_PAL_50HZ
- ||
- hdmi_video_output_cmd.video_output_cea_vesa ==
- AV8100_CEA6_7_NTSC_60HZ
- ) {
- hdmi_video_input_cmd.video_mode = AV8100_VIDEO_INTERLACE;
- } else {
- hdmi_video_input_cmd.video_mode = AV8100_VIDEO_PROGRESSIVE;
- }
+ case AV8100_COMMAND_INFOFRAMES:
+ memcpy(&av8100_config->hdmi_infoframes_cmd,
+ &config->infoframes_format,
+ sizeof(struct av8100_infoframes_format_cmd));
+ break;
- hdmi_pattern_generator_cmd.pattern_audio_mode = AV8100_PATTERN_AUDIO_OFF;
- hdmi_pattern_generator_cmd.pattern_type = AV8100_PATTERN_GENERATOR;
+ case AV8100_COMMAND_EDID_SECTION_READBACK:
+ memcpy(&av8100_config->hdmi_edid_section_readback_cmd,
+ &config->edid_section_readback_format,
+ sizeof(struct
+ av8100_edid_section_readback_format_cmd));
+ break;
- if(hdmi_video_output_cmd.video_output_cea_vesa == AV8100_CEA4_1280X720P_60HZ)
- hdmi_pattern_generator_cmd.pattern_video_format = AV8100_PATTERN_720P;
- else if(hdmi_video_output_cmd.video_output_cea_vesa == AV8100_CEA1_640X480P_59_94HZ)
- hdmi_pattern_generator_cmd.pattern_video_format = AV8100_PATTERN_VGA;
- else if(hdmi_video_output_cmd.video_output_cea_vesa == AV8100_CEA34_1920X1080P_30HZ)
- hdmi_pattern_generator_cmd.pattern_video_format = AV8100_PATTERN_1080P;
- else
- hdmi_pattern_generator_cmd.pattern_video_format = AV8100_PATTERN_720P;
+ case AV8100_COMMAND_PATTERNGENERATOR:
+ memcpy(&av8100_config->hdmi_pattern_generator_cmd,
+ &config->pattern_generator_format,
+ sizeof(struct av8100_pattern_generator_format_cmd));
+ break;
- hdmi_denc_cmd.denc = AV8100_DENC_OFF;
+ case AV8100_COMMAND_FUSE_AES_KEY:
+ memcpy(&av8100_config->hdmi_fuse_aes_key_cmd,
+ &config->fuse_aes_key_format,
+ sizeof(struct av8100_fuse_aes_key_format_cmd));
+ break;
- /* default audio configurations in i2s mode*/
- hdmi_audio_input_cmd.audio_input_if_format = AV8100_AUDIO_I2SDELAYED_MODE; // mode of the MSP
- hdmi_audio_input_cmd.i2s_input_nb = 1; // 0, 1 2 3 4
- hdmi_audio_input_cmd.sample_audio_freq = AV8100_AUDIO_FREQ_48KHZ;
- hdmi_audio_input_cmd.audio_word_lg = AV8100_AUDIO_16BITS;
- hdmi_audio_input_cmd.audio_format = AV8100_AUDIO_LPCM_MODE;
- hdmi_audio_input_cmd.audio_if_mode = AV8100_AUDIO_MASTER;
- hdmi_audio_input_cmd.audio_mute = AV8100_AUDIO_MUTE_DISABLE;
+ default:
+ return AV8100_FAIL;
+ break;
+ }
-#endif /* if..else CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV */
- // HDMI mode
- hdmi_cmd.hdmi_mode = AV8100_HDMI_ON;
- hdmi_cmd.hdmi_format = AV8100_HDMI;
- return;
+ return 0;
}
-
-#if defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI ||\
- defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
-static mcde_video_mode av8100_get_mcde_video_mode(av8100_output_CEA_VESA format)
+int av8100_configuration_write(enum av8100_command_type command_type,
+ u8 *return_buffer_length,
+ u8 *return_buffer, enum interface_type if_type)
{
- mcde_video_mode retval = VMODE_1280_720_60_P;
+ int retval = 0;
+ u8 cmd_buffer[AV8100_COMMAND_MAX_LENGTH];
+ u32 cmd_length = 0;
+ struct i2c_client *i2c;
-#define PRNK_MODE(_m, _n) \
- printk(KERN_DEBUG "AV8100 mapped mode: " #_m " on " #_n "\n");
+ if (return_buffer_length)
+ *return_buffer_length = 0;
- switch(format) {
- case AV8100_CEA1_640X480P_59_94HZ:
- PRNK_MODE(AV8100_CEA1_640X480P_59_94HZ, VMODE_640_480_60_P);
- retval = VMODE_640_480_60_P;
+ if (!av8100_config)
+ return AV8100_FAIL;
+
+ i2c = av8100_config->client;
+
+ memset(&cmd_buffer, 0x00, AV8100_COMMAND_MAX_LENGTH);
+
+#ifdef AV8100_DEBUG_EXTRA
+#define PRNK_MODE(_m) printk(KERN_DEBUG "cmd: " #_m "\n");
+#else
+#define PRNK_MODE(_m)
+#endif
+
+ /* Fill the command buffer with configuration data */
+ switch (command_type) {
+ case AV8100_COMMAND_VIDEO_INPUT_FORMAT:
+ PRNK_MODE(AV8100_COMMAND_VIDEO_INPUT_FORMAT);
+ configuration_video_input_get(cmd_buffer, &cmd_length);
break;
- case AV8100_CEA2_3_720X480P_59_94HZ:
- PRNK_MODE(AV8100_CEA2_3_720X480P_59_94HZ, VMODE_720_480_60_P);
- retval = VMODE_720_480_60_P;
+
+ case AV8100_COMMAND_AUDIO_INPUT_FORMAT:
+ PRNK_MODE(AV8100_COMMAND_AUDIO_INPUT_FORMAT);
+ configuration_audio_input_get(cmd_buffer, &cmd_length);
break;
- case AV8100_CEA5_1920X1080I_60HZ:
- PRNK_MODE(AV8100_CEA5_1920X1080I_60HZ, VMODE_1920_1080_60_I);
- retval = VMODE_1920_1080_60_I;
+
+ case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT:
+ PRNK_MODE(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT);
+ configuration_video_output_get(cmd_buffer, &cmd_length);
break;
- case AV8100_CEA6_7_NTSC_60HZ:
- PRNK_MODE(AV8100_CEA6_7_NTSC_60HZ, VMODE_720_480_60_I);
- retval = VMODE_720_480_60_I;
+
+ case AV8100_COMMAND_VIDEO_SCALING_FORMAT:
+ PRNK_MODE(AV8100_COMMAND_VIDEO_SCALING_FORMAT);
+ configuration_video_scaling_get(cmd_buffer,
+ &cmd_length);
break;
- case AV8100_CEA4_1280X720P_60HZ:
- PRNK_MODE(AV8100_CEA4_1280X720P_60HZ, VMODE_1280_720_60_P);
- retval = VMODE_1280_720_60_P;
+
+ case AV8100_COMMAND_COLORSPACECONVERSION:
+ PRNK_MODE(AV8100_COMMAND_COLORSPACECONVERSION);
+ configuration_colorspace_conversion_get(cmd_buffer,
+ &cmd_length);
break;
- case AV8100_CEA17_18_720X576P_50HZ:
- PRNK_MODE(AV8100_CEA17_18_720X576P_50HZ, VMODE_720_576_50_P);
- retval = VMODE_720_576_50_P;
+
+ case AV8100_COMMAND_CEC_MESSAGE_WRITE:
+ PRNK_MODE(AV8100_COMMAND_CEC_MESSAGE_WRITE);
+ configuration_cec_message_write_get(cmd_buffer,
+ &cmd_length);
break;
- case AV8100_CEA19_1280X720P_50HZ:
- PRNK_MODE(AV8100_CEA19_1280X720P_50HZ, VMODE_1280_720_50_P);
- retval = VMODE_1280_720_50_P;
+
+ case AV8100_COMMAND_CEC_MESSAGE_READ_BACK:
+ PRNK_MODE(AV8100_COMMAND_CEC_MESSAGE_READ_BACK);
+ configuration_cec_message_read_get(cmd_buffer,
+ &cmd_length);
break;
- case AV8100_CEA20_1920X1080I_50HZ:
- PRNK_MODE(AV8100_CEA20_1920X1080I_50HZ, VMODE_1920_1080_50_I);
- retval = VMODE_1920_1080_50_I;
+
+ case AV8100_COMMAND_DENC:
+ PRNK_MODE(AV8100_COMMAND_DENC);
+ configuration_denc_get(cmd_buffer, &cmd_length);
break;
- case AV8100_CEA21_22_576I_PAL_50HZ:
- PRNK_MODE(AV8100_CEA21_22_576I_PAL_50HZ, VMODE_720_576_50_I);
- retval = VMODE_720_576_50_I;
+
+ case AV8100_COMMAND_HDMI:
+ PRNK_MODE(AV8100_COMMAND_HDMI);
+ configuration_hdmi_get(cmd_buffer, &cmd_length);
break;
- case AV8100_CEA32_1920X1080P_24HZ:
- PRNK_MODE(AV8100_CEA32_1920X1080P_24HZ, VMODE_1920_1080_24_P);
- retval = VMODE_1920_1080_24_P;
+
+ case AV8100_COMMAND_HDCP_SENDKEY:
+ PRNK_MODE(AV8100_COMMAND_HDCP_SENDKEY);
+ configuration_hdcp_sendkey_get(cmd_buffer, &cmd_length);
break;
- case AV8100_CEA33_1920X1080P_25HZ:
- PRNK_MODE(AV8100_CEA33_1920X1080P_25HZ, VMODE_1920_1080_25_P);
- retval = VMODE_1920_1080_25_P;
+
+ case AV8100_COMMAND_HDCP_MANAGEMENT:
+ PRNK_MODE(AV8100_COMMAND_HDCP_MANAGEMENT);
+ configuration_hdcp_management_get(cmd_buffer,
+ &cmd_length);
break;
- case AV8100_CEA34_1920X1080P_30HZ:
- PRNK_MODE(AV8100_CEA34_1920X1080P_30HZ, VMODE_1920_1080_30_P);
- retval = VMODE_1920_1080_30_P;
+
+ case AV8100_COMMAND_INFOFRAMES:
+ PRNK_MODE(AV8100_COMMAND_INFOFRAMES);
+ configuration_infoframe_get(cmd_buffer, &cmd_length);
break;
- case AV8100_CEA60_1280X720P_24HZ:
- PRNK_MODE(AV8100_CEA60_1280X720P_24HZ, VMODE_1280_720_24_P);
- retval = VMODE_1280_720_24_P;
+
+ case AV8100_COMMAND_EDID_SECTION_READBACK:
+ PRNK_MODE(AV8100_COMMAND_EDID_SECTION_READBACK);
+ av8100_edid_section_readback_get(cmd_buffer, &cmd_length);
break;
- case AV8100_CEA62_1280X720P_30HZ:
- PRNK_MODE(AV8100_CEA62_1280X720P_30HZ, VMODE_1280_720_30_P);
- retval = VMODE_1280_720_30_P;
+
+ case AV8100_COMMAND_PATTERNGENERATOR:
+ PRNK_MODE(AV8100_COMMAND_PATTERNGENERATOR);
+ configuration_pattern_generator_get(cmd_buffer,
+ &cmd_length);
+ break;
+
+ case AV8100_COMMAND_FUSE_AES_KEY:
+ PRNK_MODE(AV8100_COMMAND_FUSE_AES_KEY);
+ configuration_fuse_aes_key_get(cmd_buffer, &cmd_length);
break;
- case AV8100_VESA9_800X600P_60_32HZ:
- case AV8100_CEA14_15_480p_60HZ:
- case AV8100_CEA16_1920X1080P_60HZ:
- case AV8100_CEA29_30_576P_50HZ:
- case AV8100_CEA31_1920x1080P_50Hz:
- case AV8100_CEA61_1280X720P_25HZ:
- case AV8100_VESA14_848X480P_60HZ:
- case AV8100_VESA16_1024X768P_60HZ:
- case AV8100_VESA22_1280X768P_59_99HZ:
- case AV8100_VESA23_1280X768P_59_87HZ:
- case AV8100_VESA27_1280X800P_59_91HZ:
- case AV8100_VESA28_1280X800P_59_81HZ:
- case AV8100_VESA39_1360X768P_60_02HZ:
- case AV8100_VESA81_1366X768P_59_79HZ:
default:
- /* TODO */
- PRNK_MODE(AV8100_UNKNOWN_OR_TODO_MODE, VMODE_1280_720_60_P);
- retval = VMODE_1280_720_60_P;
+ printk(KERN_INFO "Invalid command type\n");
+ retval = AV8100_INVALID_COMMAND;
break;
}
- return retval;
-}
+ LOCK_AV8100_HW;
+
+ if (if_type == I2C_INTERFACE) {
+#ifdef AV8100_DEBUG_EXTRA
+ {
+ int cnt = 0;
+ printk(KERN_DEBUG "av8100_configuration_write cmd_type:%02x length:%02x ",
+ command_type, cmd_length);
+ printk(KERN_DEBUG "buffer: ");
+ while (cnt < cmd_length) {
+ printk(KERN_DEBUG "%02x ", cmd_buffer[cnt]);
+ cnt++;
+ }
+ printk(KERN_DEBUG "\n");
+ }
#endif
-static void av8100_set_state(av8100_operating_mode state)
-{
- g_av8100_state = state;
-}
+ /* Write the command buffer */
+ retval = write_multi_byte(i2c,
+ AV8100_COMMAND_OFFSET + 1, cmd_buffer, cmd_length);
+ if (retval) {
+ UNLOCK_AV8100_HW;
+ return retval;
+ }
-static av8100_operating_mode av8100_get_state(void)
-{
- return g_av8100_state;
-}
+ /* Write the command */
+ retval = write_single_byte(i2c, AV8100_COMMAND_OFFSET,
+ command_type);
+ if (retval) {
+ UNLOCK_AV8100_HW;
+ return retval;
+ }
+ /* TODO */
+ mdelay(100);
-#ifdef AV8100_USE_KERNEL_THREAD
-/**
- * av8100_thread() - This function will be used to send the data from 8500(MCDE/VTG) to hdmi chip.
- *
- **/
-static int av8100_thread(void)
+ retval = get_command_return_data(i2c, command_type, cmd_buffer,
+ return_buffer_length, return_buffer);
+ } else if (if_type == DSI_INTERFACE) {
+ /* TODO */
+ } else {
+ retval = AV8100_INVALID_INTERFACE;
+ printk(KERN_INFO "Invalid command type\n");
+ }
+
+ if (command_type == AV8100_COMMAND_HDMI) {
+ g_av8100_status.hdmi_on = ((av8100_config->hdmi_cmd.
+ hdmi_mode == AV8100_HDMI_ON) &&
+ (av8100_config->hdmi_cmd.hdmi_format == AV8100_HDMI));
+ }
+
+ UNLOCK_AV8100_HW;
+ return retval;
+}
+
+int av8100_configuration_write_raw(enum av8100_command_type command_type,
+ u8 buffer_length,
+ u8 *buffer,
+ u8 *return_buffer_length,
+ u8 *return_buffer)
{
- int retval = AV8100_OK;
- char val = 0x0;
+ int retval = 0;
+ struct i2c_client *i2c;
- daemonize("hdmi_feeding_thread");
- allow_signal(SIGKILL);
+ LOCK_AV8100_HW;
- while (1)
- {
- wait_event_interruptible(av8100_event, (av8100_flag == 1) );
- av8100_flag = 0;
+ if (return_buffer_length)
+ *return_buffer_length = 0;
- /* STANDBY interrupts */
- retval = av8100_read_single_byte(av8100Data->client, STANDBY_PENDING_INTERRUPT_REG, &val);
- if(retval != AV8100_OK)
- {
- printk("Failed to read the STANDBY_PENDING_INTERRUPT_REG\n");
- return -EFAULT;
- }
+ if (!av8100_config) {
+ retval = AV8100_FAIL;
+ goto av8100_configuration_write_raw_out;
+ }
- if (val && HDMI_HOTPLUG_INTERRUPT) {
- //printk("HDMI_HOTPLUG_INTERRUPT\n");
+ i2c = av8100_config->client;
- /* TODO */
- }
+ /* Write the command buffer */
+ retval = write_multi_byte(i2c,
+ AV8100_COMMAND_OFFSET + 1, buffer, buffer_length);
+ if (retval)
+ goto av8100_configuration_write_raw_out;
- if (val && CVBS_PLUG_INTERRUPT) {
- //printk("CVBS_PLUG_INTERRUPT\n");
+ /* Write the command */
+ retval = write_single_byte(i2c, AV8100_COMMAND_OFFSET,
+ command_type);
+ if (retval)
+ goto av8100_configuration_write_raw_out;
- /* TODO */
- }
+ /* TODO */
+ mdelay(100);
- /* Clear interrupts */
- av8100_write_single_byte(av8100Data->client, STANDBY_PENDING_INTERRUPT_REG, STANDBY_INTERRUPT_MASK_ALL);
+ retval = get_command_return_data(i2c, command_type, buffer,
+ return_buffer_length, return_buffer);
- /* General interrupts */
- retval = av8100_read_single_byte(av8100Data->client, GENERAL_INTERRUPT_REG, &val);
- if(retval != AV8100_OK)
- {
- printk("Failed to read the GENERAL_INTERRUPT_REG\n");
- return -EFAULT;
- }
+av8100_configuration_write_raw_out:
+ UNLOCK_AV8100_HW;
+ return retval;
+}
- if(val & TE_INTERRUPT)
- {
- u8500_mcde_tasklet_4(0);
+struct av8100_status av8100_status_get(void)
+{
+ return g_av8100_status;
+}
+
+enum av8100_output_CEA_VESA av8100_video_output_format_get(int xres,
+ int yres,
+ int htot,
+ int vtot,
+ bool interlaced)
+{
+ enum av8100_output_CEA_VESA index = 1;
+ int yres_div = (interlaced == false ? 1 : 2);
+
+ while (index < sizeof(av8100_all_cea)/sizeof(struct av8100_cea)) {
+ if ((xres == av8100_all_cea[index].hactive) &&
+ (yres == av8100_all_cea[index].vactive * yres_div) &&
+ (htot == av8100_all_cea[index].htotale) &&
+ (vtot == av8100_all_cea[index].vtotale)) {
+ goto av8100_video_output_format_get_out;
}
+ index++;
+ }
- if(val & UNDER_OVER_FLOW_INTERRUPT)
- {
- //printk("Received the underflow/overflow interrupt\n");
+av8100_video_output_format_get_out:
+ /* TODO remove */
+ printk(KERN_DEBUG "av8100_video_output_format_get %d %d %d %d %d\n",
+ xres, yres, htot, vtot, index);
+ return index;
+}
- /* TODO */
- }
+static int av8100_open(struct inode *inode, struct file *filp)
+{
+ printk(KERN_DEBUG "av8100_open is called\n");
+ return 0;
+}
- /* Clear interrupts */
- retval = av8100_write_single_byte(av8100Data->client, GENERAL_INTERRUPT_REG, GENERAL_INTERRUPT_MASK_ALL);
- }
+static int av8100_release(struct inode *inode, struct file *filp)
+{
+ printk(KERN_DEBUG "av8100_release is called\n");
return 0;
}
-#endif
-/**
- * av8100_probe() - This function will be used to powerup and initialize the av8100.
- * @i2c: i2c client device
- * @id: device id
- *
- **/
-static int av8100_probe(struct i2c_client *i2cClient,
- const struct i2c_device_id *id)
+static int av8100_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
- int ret= 0;
-#if defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI ||\
- defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- mcde_video_mode mcde_mode;
-#endif
+ return 0;
+}
-#ifndef TEST_PATTERN_TEST
+static int __devinit av8100_probe(struct i2c_client *i2cClient,
+ const struct i2c_device_id *id)
+{
+ int ret = 0;
struct av8100_platform_data *pdata = i2cClient->dev.platform_data;
-#endif
- //printk(KERN_INFO "av8100 probe\n");
- //printk("av8100 probe\n");
+ printk(KERN_DEBUG "%s\n", __func__);
- PRNK_COL(PRNK_COL_GREEN);
- printk(KERN_DEBUG "av8100_probe\n");
- PRNK_COL(PRNK_COL_WHITE);
+ g_av8100_status.av8100_state = AV8100_OPMODE_SHUTDOWN;
+ g_av8100_status.av8100_plugin_status = AV8100_PLUGIN_NONE;
+ g_av8100_status.hdmi_on = false;
- av8100_init_config_params();
-
-#ifdef CONFIG_MCDE_ENABLE_FEATURE_HW_V1_SUPPORT
-#if defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_HDMI ||\
- defined CONFIG_FB_U8500_MCDE_CHANNELA_DISPLAY_SDTV
- mcde_mode = av8100_get_mcde_video_mode(hdmi_video_output_cmd.video_output_cea_vesa);
- PRNK_COL(PRNK_COL_GREEN);
- printk(KERN_DEBUG "av8100_probe: mcde_hdmi_display_init_command_mode\n");
- PRNK_COL(PRNK_COL_WHITE);
- mcde_hdmi_display_init_command_mode(mcde_mode);
-#endif
-#endif /* CONFIG_MCDE_ENABLE_FEATURE_HW_V1_SUPPORT */
-
- /** Register av8100 driver */
- ret = misc_register(&av8100_miscdev);
+ ret = av8100_config_init();
if (ret) {
- printk("registering av8100 driver as misc device fails\n");
- goto av8100_misc_fail;
- }
- if (!i2c_check_functionality(i2cClient->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_READ_WORD_DATA)) {
- ret = -ENODEV;
- goto err;
+ pr_info("av8100_config_init failed\n");
+ goto err;
}
- av8100Data = kcalloc(1, sizeof(*av8100Data), GFP_KERNEL);
- if(!av8100Data) {
- ret = -ENOMEM;
+ if (!i2c_check_functionality(i2cClient->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_READ_WORD_DATA)) {
+ ret = -ENODEV;
+ pr_info("av8100 i2c_check_functionality failed\n");
goto err;
}
- init_waitqueue_head(&av8100_event);
- //INIT_WORK(&av8100Data->work, u8500_av8100_wq);
- av8100Data->client = i2cClient;
- i2c_set_clientdata(i2cClient,av8100Data);
- /* Test pattern is local to AV8100 driver so if set no MCDE probe as no interaction with it */
- if(mcde_get_hdmi_flag())
- {
- printk("HDMI is included in the menuconfig\n");
-
- /** powerup the av8100IC */
- ret = av8100_powerup(i2cClient, id);
- if(ret != AV8100_OK){
- printk("error in init the hdmi client\n");
- goto err;
- }
- g_av8100_state = AV8100_OPMODE_INIT;
-
- ret = av8100_download_firmware(i2cClient, FIRMWARE_DOWNLOAD_ENTRY_REG, av8100_fw_buff, fw_size, I2C_INTERFACE);
- if(ret != AV8100_OK){
- printk("error in av8100 firmware download: failed\n");
- goto err;
- }
-
- av8100_configure_hdmi(i2cClient);
+ init_waitqueue_head(&av8100_event);
-#ifndef TEST_PATTERN_TEST
-#ifdef AV8100_USE_KERNEL_THREAD
- kernel_thread((void*)av8100_thread, NULL, CLONE_FS | CLONE_SIGHAND);
-#endif
+ av8100_config->client = i2cClient;
+ av8100_config->id = (struct i2c_device_id *) id;
+ i2c_set_clientdata(i2cClient, av8100_config);
- ret = request_irq(pdata->irq, av8100_intr_handler,
- IRQF_TRIGGER_RISING, "av8100", av8100Data);
- if (ret) {
- printk(KERN_ERR "unable to request for the irq %d\n", GPIO_TO_IRQ(192));
- gpio_free(pdata->irq);
- goto err;
- }
- ret = av8100_enable_interrupt(i2cClient);
- if(ret != AV8100_OK){
- printk("error in enabling the interrupts\n");
- goto err;
- }
+ kthread_run(av8100_thread, NULL, "hdmi_thread");
- av8100_hdmi_on(av8100Data);
-#endif /* TEST_PATTERN_TEST */
+ ret = request_irq(pdata->irq, av8100_intr_handler,
+ IRQF_TRIGGER_RISING, "av8100", av8100_config);
+ if (ret) {
+ printk(KERN_ERR "av8100_hw request_irq %d failed %d\n",
+ pdata->irq, ret);
+ gpio_free(pdata->irq);
+ goto err;
}
+
return ret;
err:
- kfree(i2cClient);
-av8100_misc_fail:
return ret;
}
-
-/**
- * av8100_remove() - This function will be used to unload the av8100 driver.
- * @i2c: i2c client device
- *
- **/
-static int __exit av8100_remove(struct i2c_client *i2cClient)
+static int __devexit av8100_remove(struct i2c_client *i2cClient)
{
- i2c_set_clientdata(i2cClient,NULL);
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ av8100_config_exit();
+
return 0;
}
-static const struct i2c_device_id av8100_id[] = {
- { "av8100", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, av8100);
+int av8100_init(void)
+{
+ int ret;
-static struct i2c_driver av8100_driver = {
- .driver = {
- .name = "av8100",
- .owner = THIS_MODULE,
- },
- .probe = av8100_probe,
- .remove = __exit_p(av8100_remove),
- .id_table = av8100_id,
-};
+ printk(KERN_DEBUG "%s\n", __func__);
-static int __init av8100_init(void)
-{
- return i2c_add_driver(&av8100_driver);
-}
+ ret = i2c_add_driver(&av8100_driver);
+ if (ret) {
+ printk(KERN_DEBUG "av8100 i2c_add_driver failed\n");
+ goto av8100_init_err;
+ }
+ ret = misc_register(&av8100_miscdev);
+ if (ret) {
+ printk(KERN_DEBUG "av8100 misc_register failed\n");
+ goto av8100_init_err;
+ }
+
+ hdmi_init();
+
+ return ret;
+
+av8100_init_err:
+ return ret;
+}
module_init(av8100_init);
-static void __exit av8100_exit(void)
+
+void av8100_exit(void)
{
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ hdmi_exit();
+
+ misc_deregister(&av8100_miscdev);
i2c_del_driver(&av8100_driver);
}
-
module_exit(av8100_exit);
+
+MODULE_AUTHOR("Per Persson <per.xb.persson@stericsson.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ST-Ericsson hdmi display driver");