diff options
author | Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com> | 2011-09-02 14:32:44 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:04:03 +0200 |
commit | e93779c0ff373da86b408f3ee92a9e28ddcc8b32 (patch) | |
tree | 2bc706a59141d7af885c511ce8576611fbd4ed75 | |
parent | ad80a9b90974f8962be2b9670d73f9b50ddffa7e (diff) |
hdmi: Kernel 3.0 migration changes
Migrate the following hdmi driver patches to kernel 3.0
6b7eafe video: av8100: Resume time too long
f1f105b video: av8100: Fix warnings
4de90f0 video: av8100: Add underflow detection
10470aa video: av8100: Use Linux error codes
223a03b video: av8100: Get chip cut version
0dd4c53 video: mcde: Fix Coverity defects
59346ca video: av8100: Avoid multiple firmware downloads
2814baa video: hdmi: Avoid global variables
ST-Ericsson ID: 352334
ST-Ericsson Linux next: NA
ST-Ericsson FOSS-OUT ID: NA
Signed-off-by: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com>
Change-Id: I853eb0351e9ed4e0e7f806e76d3df6ab3e4419b2
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30013
-rw-r--r-- | drivers/video/av8100/av8100.c | 1689 | ||||
-rw-r--r-- | drivers/video/av8100/hdmi.c | 975 | ||||
-rw-r--r-- | drivers/video/av8100/hdmi_loc.h | 2 | ||||
-rw-r--r-- | include/video/av8100.h | 10 |
4 files changed, 1438 insertions, 1238 deletions
diff --git a/drivers/video/av8100/av8100.c b/drivers/video/av8100/av8100.c index 924bf502c77..7ce61a83f1f 100644 --- a/drivers/video/av8100/av8100.c +++ b/drivers/video/av8100/av8100.c @@ -26,6 +26,7 @@ #include <linux/mutex.h> #include <linux/slab.h> #include <linux/clk.h> +#include <linux/list.h> #include <linux/regulator/consumer.h> #include <mach/prcmu.h> @@ -36,6 +37,8 @@ #define AV8100_FW_FILENAME "av8100.fw" +#define AV8100_DEVNR_DEFAULT 0 + /* Interrupts */ #define AV8100_INT_EVENT 0x1 #define AV8100_PLUGSTARTUP_EVENT 0x4 @@ -49,6 +52,7 @@ /* Command offsets */ #define AV8100_COMMAND_OFFSET 0x10 +#define AV8100_CUTVER_OFFSET 0x11 #define AV8100_COMMAND_MAX_LENGTH 0x81 #define AV8100_CMD_BUF_OFFSET (AV8100_COMMAND_OFFSET + 1) #define AV8100_2ND_RET_BYTE_OFFSET (AV8100_COMMAND_OFFSET + 1) @@ -109,27 +113,12 @@ #define AV8100_WAITTIME_50MS 50 #define AV8100_WATTIME_100US 100 -/* Master clock timing */ -#define MCLK_RNG_17_22 0 /* Use with 19.2 MHZ clock */ -#define MCLK_RNG_22_27 1 -#define MCLK_RNG_27_33 2 -#define MCLK_RNG_31_38 3 /* Use with 38.4 MHZ clock */ -#define MCLK_RNG_36_44 4 -#define MCLK_RNG_40_49 5 -#define MCLK_RNG_45_55 6 -#define MCLK_RNG_49_60 7 -#define MCLK_RNG_54_66 8 -#define MCLK_RNG_58_71 9 -#define MCLK_RNG_63_77 10 -#define MCLK_RNG_67_82 11 -#define MCLK_RNG_72_88 12 -#define MCLK_RNG_76_93 13 -#define MCLK_RNG_85_104 14 -#define MCLK_RNG_94_115 15 - -DEFINE_MUTEX(av8100_hw_mutex); +static DEFINE_MUTEX(av8100_hw_mutex); #define LOCK_AV8100_HW mutex_lock(&av8100_hw_mutex) #define UNLOCK_AV8100_HW mutex_unlock(&av8100_hw_mutex) +static DEFINE_MUTEX(av8100_fwdl_mutex); +#define LOCK_AV8100_FWDL mutex_lock(&av8100_fwdl_mutex) +#define UNLOCK_AV8100_FWDL mutex_unlock(&av8100_fwdl_mutex) struct color_conversion_cmd { unsigned short c0; @@ -150,7 +139,7 @@ struct color_conversion_cmd { unsigned char cmin; }; -struct av8100_config_t { +struct av8100_config { struct i2c_client *client; struct i2c_device_id *id; struct av8100_video_input_format_cmd hdmi_video_input_cmd; @@ -180,7 +169,7 @@ enum av8100_plug_state { AV8100_PLUGGED }; -struct av8100_globals_t { +struct av8100_params { int denc_off_time;/* 5 volt time */ int hdmi_off_time;/* 5 volt time */ int on_time;/* 5 volt time */ @@ -188,6 +177,7 @@ struct av8100_globals_t { u8 cpdm;/*stby_int_mask*/ u8 cecm;/*gen_int_mask*/ u8 hdcpm;/*gen_int_mask*/ + u8 uovbm;/*gen_int_mask*/ void (*hdmi_ev_cb)(enum av8100_hdmi_event); enum av8100_plug_state plug_state; struct clk *inputclk; @@ -248,33 +238,41 @@ enum av8100_command_size { AV8100_COMMAND_FUSE_AES_CHK_SIZE = 0x2, }; -static unsigned int waittime_retry[10] = {1, 2, 4, 6, 8, 10, 10, 10, 10, 10}; +struct av8100_device { + struct list_head list; + struct miscdevice miscdev; + struct device *dev; + struct av8100_config config; + struct av8100_status status; + struct timer_list timer; + wait_queue_head_t event; + int flag; + struct av8100_params params; + u8 chip_version; +}; + +static const unsigned int waittime_retry[10] = { + 1, 2, 4, 6, 8, 10, 10, 10, 10, 10}; static int av8100_5V_w(u8 denc_off, u8 hdmi_off, u8 on); -static void clr_plug_status(enum av8100_plugin_status status); -static void set_plug_status(enum av8100_plugin_status status); -static void cec_rx(void); -static void cec_tx(void); -static void cec_txerr(void); -static void hdcp_changed(void); +static void clr_plug_status(struct av8100_device *adev, + enum av8100_plugin_status status); +static void set_plug_status(struct av8100_device *adev, + enum av8100_plugin_status status); +static void cec_rx(struct av8100_device *adev); +static void cec_tx(struct av8100_device *adev); +static void cec_txerr(struct av8100_device *adev); +static void hdcp_changed(struct av8100_device *adev); static const struct color_conversion_cmd *get_color_transform_cmd( + struct av8100_device *adev, enum av8100_color_transform transform); static int av8100_open(struct inode *inode, struct file *filp); static int av8100_release(struct inode *inode, struct file *filp); static long av8100_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -static int __devinit av8100_probe(struct i2c_client *i2cClient, +static int __devinit av8100_probe(struct i2c_client *i2c_client, 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}; -static struct timer_list av8100_plugtimer; -static wait_queue_head_t av8100_event; -static int av8100_flag = 0x0; -static struct av8100_globals_t *av8100_globals; -static u8 chip_version; -struct device *av8100dev; +static int __devexit av8100_remove(struct i2c_client *i2c_client); static const struct file_operations av8100_fops = { .owner = THIS_MODULE, @@ -283,13 +281,10 @@ static const struct file_operations av8100_fops = { .unlocked_ioctl = av8100_ioctl }; -static struct miscdevice av8100_miscdev = { - MISC_DYNAMIC_MINOR, - "av8100", - &av8100_fops -}; +/* List of devices */ +static LIST_HEAD(av8100_device_list); -struct av8100_cea av8100_all_cea[29] = { +static const struct av8100_cea av8100_all_cea[29] = { /* cea id * cea_nr vtot vact vsbpp vslen * vsfp vpol htot hact hbp hslen hfp freq @@ -483,23 +478,76 @@ static const struct i2c_device_id av8100_id[] = { { } }; +static struct av8100_device *devnr_to_adev(int devnr) +{ + /* Get device from list of devices */ + struct list_head *element; + struct av8100_device *av8100_dev; + int cnt = 0; + + list_for_each(element, &av8100_device_list) { + av8100_dev = list_entry(element, struct av8100_device, list); + if (cnt == devnr) + return av8100_dev; + cnt++; + } + + return NULL; +} + +static struct av8100_device *dev_to_adev(struct device *dev) +{ + /* Get device from list of devices */ + struct list_head *element; + struct av8100_device *av8100_dev; + int cnt = 0; + + list_for_each(element, &av8100_device_list) { + av8100_dev = list_entry(element, struct av8100_device, list); + if (av8100_dev->dev == dev) + return av8100_dev; + cnt++; + } + + return NULL; +} + +static int adev_to_devnr(struct av8100_device *adev) +{ + /* Get devnr from list of devices */ + struct list_head *element; + struct av8100_device *av8100_dev; + int cnt = 0; + + list_for_each(element, &av8100_device_list) { + av8100_dev = list_entry(element, struct av8100_device, list); + if (av8100_dev == adev) + return cnt; + cnt++; + } + + return -EINVAL; +} + #ifdef CONFIG_PM static int av8100_suspend(struct i2c_client *i2c_client, pm_message_t state) { int ret = 0; + struct av8100_device *adev; - dev_dbg(av8100dev, "%s\n", __func__); + adev = dev_to_adev(&i2c_client->dev); + if (!adev) + return -EFAULT; - if (!av8100_globals) - return ret; + dev_dbg(adev->dev, "%s\n", __func__); - av8100_globals->pre_suspend_power = + adev->params.pre_suspend_power = (av8100_status_get().av8100_state > AV8100_OPMODE_SHUTDOWN); - if (av8100_globals->pre_suspend_power) { + if (adev->params.pre_suspend_power) { ret = av8100_powerdown(); if (ret) - dev_err(av8100dev, "av8100_powerdown failed\n"); + dev_err(adev->dev, "av8100_powerdown failed\n"); } return ret; @@ -509,29 +557,35 @@ static int av8100_resume(struct i2c_client *i2c_client) { int ret; u8 hpds = 0; + struct av8100_device *adev; - dev_dbg(av8100dev, "%s\n", __func__); + adev = dev_to_adev(&i2c_client->dev); + if (!adev) + return -EFAULT; - if (av8100_globals->pre_suspend_power) { - ret = av8100_powerup(); - if (ret) { - dev_err(av8100dev, "av8100_powerup failed\n"); - return ret; - } + dev_dbg(adev->dev, "%s\n", __func__); - /* Check HDMI plug status */ - if (av8100_reg_stby_r(NULL, NULL, &hpds, NULL, NULL)) { - dev_warn(av8100dev, "av8100_reg_stby_r failed\n"); - goto av8100_resume_end; - } + if (adev->params.pre_suspend_power) { + ret = av8100_powerup(); + if (ret) { + dev_err(adev->dev, "av8100_powerup failed\n"); + return ret; + } - if (hpds) - set_plug_status(AV8100_HDMI_PLUGIN); /* Plugged*/ - else - clr_plug_status(AV8100_HDMI_PLUGIN); /* Unplugged*/ + /* Check HDMI plug status */ + if (av8100_reg_stby_r(NULL, NULL, &hpds, NULL, NULL)) { + dev_warn(adev->dev, "av8100_reg_stby_r failed\n"); + goto av8100_resume_end; + } - av8100_globals->hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_HIGH; - av8100_enable_interrupt(); + if (hpds) + set_plug_status(adev, AV8100_HDMI_PLUGIN); /* Plugged*/ + else + clr_plug_status(adev, + AV8100_HDMI_PLUGIN); /* Unplugged*/ + + adev->params.hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_HIGH; + av8100_enable_interrupt(); } av8100_resume_end: @@ -555,30 +609,32 @@ static struct i2c_driver av8100_driver = { static void av8100_plugtimer_int(unsigned long value) { - av8100_flag |= AV8100_PLUGSTARTUP_EVENT; - wake_up_interruptible(&av8100_event); - del_timer(&av8100_plugtimer); + struct av8100_device *adev; + + adev = devnr_to_adev((int)value); + adev->flag |= AV8100_PLUGSTARTUP_EVENT; + wake_up_interruptible(&adev->event); + del_timer(&adev->timer); } -static int av8100_int_event_handle(void) +static int av8100_int_event_handle(struct av8100_device *adev) { u8 hpdi = 0; u8 cpdi = 0; + u8 uovbi = 0; u8 hdcpi = 0; u8 ceci = 0; u8 hpds = 0; u8 cpds = 0; u8 hdcps = 0; + u8 onuvb = 0; u8 cectxerr = 0; u8 cecrx = 0; u8 cectx = 0; - if (!av8100_globals) - return -EINVAL; - /* STANDBY_PENDING_INTERRUPT reg */ if (av8100_reg_stby_pend_int_r(&hpdi, &cpdi, NULL, NULL)) { - dev_dbg(av8100dev, "av8100_reg_stby_pend_int_r failed\n"); + dev_dbg(adev->dev, "av8100_reg_stby_pend_int_r failed\n"); goto av8100_int_event_handle_1; } @@ -589,112 +645,113 @@ static int av8100_int_event_handle(void) /* STANDBY reg */ if (av8100_reg_stby_r(NULL, NULL, &hpds, &cpds, NULL)) { - dev_dbg(av8100dev, "av8100_reg_stby_r failed\n"); + dev_dbg(adev->dev, "av8100_reg_stby_r failed\n"); goto av8100_int_event_handle_1; } } - if (cpdi & av8100_globals->cpdm) { + if (cpdi & adev->params.cpdm) { /* TVout plugin change */ if (cpds) { - dev_dbg(av8100dev, "cpds 1\n"); - set_plug_status(AV8100_CVBS_PLUGIN); + dev_dbg(adev->dev, "cpds 1\n"); + set_plug_status(adev, AV8100_CVBS_PLUGIN); } else { - dev_dbg(av8100dev, "cpds 0\n"); - clr_plug_status(AV8100_CVBS_PLUGIN); + dev_dbg(adev->dev, "cpds 0\n"); + clr_plug_status(adev, AV8100_CVBS_PLUGIN); } } - if (hpdi & av8100_globals->hpdm) { + if (hpdi & adev->params.hpdm) { /* HDMI plugin change */ if (hpds) { /* Plugged */ /* Set 5V always on */ - av8100_5V_w(av8100_globals->denc_off_time, + av8100_5V_w(adev->params.denc_off_time, 0, - av8100_globals->on_time); - dev_dbg(av8100dev, "hpds 1\n"); - set_plug_status(AV8100_HDMI_PLUGIN); + adev->params.on_time); + dev_dbg(adev->dev, "hpds 1\n"); + set_plug_status(adev, AV8100_HDMI_PLUGIN); } else { /* Unplugged */ - av8100_5V_w(av8100_globals->denc_off_time, - av8100_globals->hdmi_off_time, - av8100_globals->on_time); - dev_dbg(av8100dev, "hpds 0\n"); - clr_plug_status(AV8100_HDMI_PLUGIN); + av8100_5V_w(adev->params.denc_off_time, + adev->params.hdmi_off_time, + adev->params.on_time); + dev_dbg(adev->dev, "hpds 0\n"); + clr_plug_status(adev, AV8100_HDMI_PLUGIN); } } av8100_int_event_handle_1: /* GENERAL_INTERRUPT reg */ if (av8100_reg_gen_int_r(NULL, NULL, NULL, &ceci, - &hdcpi, NULL, NULL)) { - dev_dbg(av8100dev, "av8100_reg_stby_pend_int_r failed\n"); + &hdcpi, &uovbi, NULL)) { + dev_dbg(adev->dev, "av8100_reg_gen_int_r failed\n"); return -EINVAL; } /* CEC or HDCP event */ - if (ceci | hdcpi) { + if (ceci | hdcpi | uovbi) { /* Clear pending interrupts */ av8100_reg_gen_int_w(1, 1, 1, 1, 1, 1); /* GENERAL_STATUS reg */ if (av8100_reg_gen_status_r(&cectxerr, &cecrx, &cectx, NULL, - NULL, &hdcps) != 0) { - dev_dbg(av8100dev, "av8100_reg_gen_status_r fail\n"); + &onuvb, &hdcps) != 0) { + dev_dbg(adev->dev, "av8100_reg_gen_status_r fail\n"); return -EINVAL; } } + /* Underflow or overflow */ + if (uovbi) + dev_dbg(adev->dev, "uovbi %d\n", onuvb); + /* CEC received */ if (ceci && cecrx) { u8 val; - dev_dbg(av8100dev, "cecrx\n"); + dev_dbg(adev->dev, "cecrx\n"); /* Clear cecrx in status reg*/ if (av8100_reg_r(AV8100_GENERAL_STATUS, &val) == 0) { if (av8100_reg_w(AV8100_GENERAL_STATUS, val & ~AV8100_GENERAL_STATUS_CECREC_MASK)) - dev_info(av8100dev, "gen_stat write error\n"); + dev_info(adev->dev, "gen_stat write error\n"); } else { - dev_info(av8100dev, "gen_stat read error\n"); + dev_info(adev->dev, "gen_stat read error\n"); } /* Report CEC event */ - cec_rx(); + cec_rx(adev); } /* CEC tx error */ if (ceci && cectx && cectxerr) { - dev_dbg(av8100dev, "cectxerr\n"); + dev_dbg(adev->dev, "cectxerr\n"); /* Report CEC tx error event */ - cec_txerr(); + cec_txerr(adev); } else if (ceci && cectx) { - dev_dbg(av8100dev, "cectx\n"); + dev_dbg(adev->dev, "cectx\n"); /* Report CEC tx event */ - cec_tx(); + cec_tx(adev); } /* HDCP event */ if (hdcpi) { - dev_dbg(av8100dev, "hdcpch:%0x\n", hdcps); + dev_dbg(adev->dev, "hdcpch:%0x\n", hdcps); /* Report HDCP status change event */ - hdcp_changed(); + hdcp_changed(adev); } return 0; } -static int av8100_plugstartup_event_handle(void) +static int av8100_plugstartup_event_handle(struct av8100_device *adev) { u8 hpds = 0; u8 cpds = 0; - if (!av8100_globals) - return -EINVAL; - - switch (av8100_globals->plug_state) { + switch (adev->params.plug_state) { case AV8100_UNPLUGGED: case AV8100_PLUGGED: default: @@ -702,31 +759,31 @@ static int av8100_plugstartup_event_handle(void) case AV8100_PLUGGED_STARTUP: /* Unmask interrupt */ - av8100_globals->hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_HIGH; - if (av8100_reg_stby_int_mask_w(av8100_globals->hpdm, - av8100_globals->cpdm, + adev->params.hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_HIGH; + if (av8100_reg_stby_int_mask_w(adev->params.hpdm, + adev->params.cpdm, AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT, AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW)) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "av8100_reg_stby_int_mask_w fail\n"); } - msleep(1); + mdelay(AV8100_WAITTIME_1MS); /* Get actual plug status */ if (av8100_reg_stby_r(NULL, NULL, &hpds, &cpds, NULL)) - dev_dbg(av8100dev, "av8100_reg_stby_r fail\n"); + dev_dbg(adev->dev, "av8100_reg_stby_r fail\n"); /* Set plugstate */ if (hpds) { - av8100_globals->plug_state = AV8100_PLUGGED; - dev_dbg(av8100dev, "plug_state:2\n"); + adev->params.plug_state = AV8100_PLUGGED; + dev_dbg(adev->dev, "plug_state:2\n"); } else { - av8100_globals->plug_state = AV8100_UNPLUGGED; - dev_dbg(av8100dev, "plug_state:0\n"); + adev->params.plug_state = AV8100_UNPLUGGED; + dev_dbg(adev->dev, "plug_state:0\n"); - if (av8100_globals->hdmi_ev_cb) - av8100_globals->hdmi_ev_cb( + if (adev->params.hdmi_ev_cb) + adev->params.hdmi_ev_cb( AV8100_HDMI_EVENT_HDMI_PLUGOUT); } break; @@ -737,22 +794,22 @@ static int av8100_plugstartup_event_handle(void) static int av8100_thread(void *p) { - u8 flags; + u8 flags; + struct av8100_device *adev = p; while (1) { - wait_event_interruptible(av8100_event, (av8100_flag != 0)); - flags = av8100_flag; - av8100_flag = 0; + wait_event_interruptible(adev->event, (adev->flag != 0)); + flags = adev->flag; + adev->flag = 0; - if (!av8100_globals || - g_av8100_status.av8100_state < AV8100_OPMODE_STANDBY) + if (adev->status.av8100_state < AV8100_OPMODE_STANDBY) continue; if (flags & AV8100_INT_EVENT) - (void)av8100_int_event_handle(); + (void)av8100_int_event_handle(adev); if (flags & AV8100_PLUGSTARTUP_EVENT) - (void)av8100_plugstartup_event_handle(); + (void)av8100_plugstartup_event_handle(adev); } return 0; @@ -760,8 +817,12 @@ static int av8100_thread(void *p) static irqreturn_t av8100_intr_handler(int irq, void *p) { - av8100_flag |= AV8100_INT_EVENT; - wake_up_interruptible(&av8100_event); + struct av8100_device *adev; + + adev = (struct av8100_device *) p; + adev->flag |= AV8100_INT_EVENT; + wake_up_interruptible(&adev->event); + return IRQ_HANDLED; } @@ -850,8 +911,8 @@ static u16 av8100_get_ui_x4( return AV8100_UI_X4_DEFAULT; } -static int av8100_config_video_output_dep(enum av8100_output_CEA_VESA - output_format) +static int av8100_config_video_output_dep( + enum av8100_output_CEA_VESA output_format) { int retval; union av8100_configuration config; @@ -919,21 +980,15 @@ static int av8100_config_video_output_dep(enum av8100_output_CEA_VESA return 0; } -static int av8100_config_init(void) +static int av8100_config_init(struct av8100_device *adev) { int retval; union av8100_configuration config; - dev_dbg(av8100dev, "%s\n", __func__); - - av8100_config = kzalloc(sizeof(struct av8100_config_t), GFP_KERNEL); - if (!av8100_config) { - dev_err(av8100dev, "%s: Failed to allocate config\n", __func__); - return AV8100_FAIL; - } + dev_dbg(adev->dev, "%s\n", __func__); memset(&config, 0, sizeof(union av8100_configuration)); - memset(av8100_config, 0, sizeof(union av8100_configuration)); + memset(&adev->config, 0, sizeof(struct av8100_config)); /* Color conversion */ config.color_transform = AV8100_COLOR_TRANSFORM_INDENTITY; @@ -1010,72 +1065,49 @@ static int av8100_config_init(void) return 0; } -static void av8100_config_exit(void) +static int av8100_params_init(struct av8100_device *adev) { - dev_dbg(av8100dev, "%s\n", __func__); - - kfree(av8100_config); - av8100_config = NULL; -} - -static int av8100_globals_init(void) -{ - dev_dbg(av8100dev, "%s\n", __func__); - - av8100_globals = kzalloc(sizeof(struct av8100_globals_t), GFP_KERNEL); - if (!av8100_globals) { - dev_err(av8100dev, "%s: Alloc failure\n", __func__); - return AV8100_FAIL; - } + dev_dbg(adev->dev, "%s\n", __func__); - av8100_globals->denc_off_time = AV8100_DENC_OFF_TIME; - av8100_globals->hdmi_off_time = AV8100_HDMI_OFF_TIME; - av8100_globals->on_time = AV8100_ON_TIME; + adev->params.denc_off_time = AV8100_DENC_OFF_TIME; + adev->params.hdmi_off_time = AV8100_HDMI_OFF_TIME; + adev->params.on_time = AV8100_ON_TIME; - av8100_globals->hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_HIGH; - av8100_globals->cpdm = AV8100_STANDBY_INTERRUPT_MASK_CPDM_HIGH; - av8100_globals->hdcpm = AV8100_GENERAL_INTERRUPT_MASK_HDCPM_HIGH; - av8100_globals->cecm = AV8100_GENERAL_INTERRUPT_MASK_CECM_HIGH; + adev->params.hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_HIGH; + adev->params.cpdm = AV8100_STANDBY_INTERRUPT_MASK_CPDM_HIGH; + adev->params.hdcpm = AV8100_GENERAL_INTERRUPT_MASK_HDCPM_HIGH; + adev->params.cecm = AV8100_GENERAL_INTERRUPT_MASK_CECM_HIGH; + adev->params.uovbm = AV8100_GENERAL_INTERRUPT_MASK_UOVBM_HIGH; - av8100_globals->plug_state = AV8100_UNPLUGGED; - av8100_globals->inputclk = NULL; - av8100_globals->inputclk_requested = false; - av8100_globals->opp_requested = false; - av8100_globals->regulator_requested = false; + adev->params.plug_state = AV8100_UNPLUGGED; + adev->params.inputclk = NULL; + adev->params.inputclk_requested = false; + adev->params.opp_requested = false; + adev->params.regulator_requested = false; return 0; } -static void av8100_globals_exit(void) +static void clr_plug_status(struct av8100_device *adev, + enum av8100_plugin_status status) { - dev_dbg(av8100dev, "%s\n", __func__); - - kfree(av8100_globals); - av8100_globals = NULL; -} - -static void clr_plug_status(enum av8100_plugin_status status) -{ - g_av8100_status.av8100_plugin_status &= ~status; + adev->status.av8100_plugin_status &= ~status; switch (status) { case AV8100_HDMI_PLUGIN: - if (!av8100_globals) - return; - - switch (av8100_globals->plug_state) { + switch (adev->params.plug_state) { case AV8100_UNPLUGGED: case AV8100_PLUGGED_STARTUP: default: break; case AV8100_PLUGGED: - av8100_globals->plug_state = + adev->params.plug_state = AV8100_UNPLUGGED; - dev_dbg(av8100dev, "plug_state:0\n"); + dev_dbg(adev->dev, "plug_state:0\n"); - if (av8100_globals->hdmi_ev_cb) - av8100_globals->hdmi_ev_cb( + if (adev->params.hdmi_ev_cb) + adev->params.hdmi_ev_cb( AV8100_HDMI_EVENT_HDMI_PLUGOUT); break; } @@ -1090,49 +1122,47 @@ static void clr_plug_status(enum av8100_plugin_status status) } } -static void set_plug_status(enum av8100_plugin_status status) +static void set_plug_status(struct av8100_device *adev, + enum av8100_plugin_status status) { - g_av8100_status.av8100_plugin_status |= status; + adev->status.av8100_plugin_status |= status; switch (status) { case AV8100_HDMI_PLUGIN: - if (!av8100_globals) - return; - - switch (av8100_globals->plug_state) { + switch (adev->params.plug_state) { case AV8100_UNPLUGGED: - av8100_globals->plug_state = + adev->params.plug_state = AV8100_PLUGGED_STARTUP; - dev_dbg(av8100dev, "plug_state:1\n"); + dev_dbg(adev->dev, "plug_state:1\n"); /* * Mask interrupts to avoid plug detect during * startup * */ - av8100_globals->hpdm = + adev->params.hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_LOW; if (av8100_reg_stby_int_mask_w( - av8100_globals->hpdm, - av8100_globals->cpdm, + adev->params.hpdm, + adev->params.cpdm, AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT, AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW)) { - dev_dbg(av8100dev, - "av8100_reg_stby_int_mask_w" - "fail\n"); + dev_dbg(adev->dev, + "av8100_reg_stby_int_mask_w fail\n"); } /* Set plug startup timer */ - init_timer(&av8100_plugtimer); - av8100_plugtimer.expires = jiffies + + init_timer(&adev->timer); + adev->timer.expires = jiffies + AV8100_PLUGSTARTUP_TIME; - av8100_plugtimer.function = + adev->timer.function = av8100_plugtimer_int; - av8100_plugtimer.data = 0; - add_timer(&av8100_plugtimer); + adev->timer.data = 0; + adev->timer.data = adev_to_devnr(adev); + mod_timer(&adev->timer, adev->timer.expires); - if (av8100_globals->hdmi_ev_cb) - av8100_globals->hdmi_ev_cb( + if (adev->params.hdmi_ev_cb) + adev->params.hdmi_ev_cb( AV8100_HDMI_EVENT_HDMI_PLUGIN); break; @@ -1152,38 +1182,39 @@ static void set_plug_status(enum av8100_plugin_status status) } } -static void cec_rx(void) +static void cec_rx(struct av8100_device *adev) { - if (av8100_globals && av8100_globals->hdmi_ev_cb) - av8100_globals->hdmi_ev_cb(AV8100_HDMI_EVENT_CEC); + if (adev->params.hdmi_ev_cb) + adev->params.hdmi_ev_cb(AV8100_HDMI_EVENT_CEC); } -static void cec_tx(void) +static void cec_tx(struct av8100_device *adev) { - if (av8100_globals && av8100_globals->hdmi_ev_cb) - av8100_globals->hdmi_ev_cb(AV8100_HDMI_EVENT_CECTX); + if (adev->params.hdmi_ev_cb) + adev->params.hdmi_ev_cb(AV8100_HDMI_EVENT_CECTX); } -static void cec_txerr(void) +static void cec_txerr(struct av8100_device *adev) { - if (av8100_globals && av8100_globals->hdmi_ev_cb) - av8100_globals->hdmi_ev_cb(AV8100_HDMI_EVENT_CECTXERR); + if (adev->params.hdmi_ev_cb) + adev->params.hdmi_ev_cb(AV8100_HDMI_EVENT_CECTXERR); } -static void hdcp_changed(void) +static void hdcp_changed(struct av8100_device *adev) { - if (av8100_globals && av8100_globals->hdmi_ev_cb) - av8100_globals->hdmi_ev_cb(AV8100_HDMI_EVENT_HDCP); + if (adev->params.hdmi_ev_cb) + adev->params.hdmi_ev_cb(AV8100_HDMI_EVENT_HDCP); } -static void av8100_set_state(enum av8100_operating_mode state) +static void av8100_set_state(struct av8100_device *adev, + enum av8100_operating_mode state) { - g_av8100_status.av8100_state = state; + adev->status.av8100_state = state; if (state <= AV8100_OPMODE_STANDBY) { - clr_plug_status(AV8100_HDMI_PLUGIN); - clr_plug_status(AV8100_CVBS_PLUGIN); - g_av8100_status.hdmi_on = false; + clr_plug_status(adev, AV8100_HDMI_PLUGIN); + clr_plug_status(adev, AV8100_CVBS_PLUGIN); + adev->status.hdmi_on = false; } } @@ -1200,10 +1231,11 @@ static int write_single_byte(struct i2c_client *client, u8 reg, u8 data) { int ret; + struct device *dev = &client->dev; ret = i2c_smbus_write_byte_data(client, reg, data); if (ret < 0) - dev_dbg(av8100dev, "i2c smbus write byte failed\n"); + dev_dbg(dev, "i2c smbus write byte failed\n"); return ret; } @@ -1221,12 +1253,13 @@ static int write_single_byte(struct i2c_client *client, u8 reg, static int read_single_byte(struct i2c_client *client, u8 reg, u8 *val) { int value; + struct device *dev = &client->dev; value = i2c_smbus_read_byte_data(client, reg); if (value < 0) { - dev_dbg(av8100dev, "i2c smbus read byte failed,read data = %x " + dev_dbg(dev, "i2c smbus read byte failed,read data = %x " "from offset:%x\n" , value, reg); - return AV8100_FAIL; + return -EFAULT; } *val = (u8) value; @@ -1247,150 +1280,139 @@ static int write_multi_byte(struct i2c_client *client, u8 reg, u8 *buf, u8 nbytes) { int ret; + struct device *dev = &client->dev; ret = i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf); if (ret < 0) - dev_dbg(av8100dev, "i2c smbus write multi byte error\n"); + dev_dbg(dev, "i2c smbus write multi byte error\n"); return ret; } -static int configuration_video_input_get(char *buffer, - unsigned int *length) +static int configuration_video_input_get(struct av8100_device *adev, + 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. + buffer[0] = adev->config.hdmi_video_input_cmd.dsi_input_mode; + buffer[1] = adev->config.hdmi_video_input_cmd.input_pixel_format; + buffer[2] = REG_16_8_MSB(adev->config.hdmi_video_input_cmd. total_horizontal_pixel); - buffer[3] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + buffer[3] = REG_16_8_LSB(adev->config.hdmi_video_input_cmd. total_horizontal_pixel); - buffer[4] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd. + buffer[4] = REG_16_8_MSB(adev->config.hdmi_video_input_cmd. total_horizontal_active_pixel); - buffer[5] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + buffer[5] = REG_16_8_LSB(adev->config.hdmi_video_input_cmd. total_horizontal_active_pixel); - buffer[6] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd. + buffer[6] = REG_16_8_MSB(adev->config.hdmi_video_input_cmd. total_vertical_lines); - buffer[7] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + buffer[7] = REG_16_8_LSB(adev->config.hdmi_video_input_cmd. total_vertical_lines); - buffer[8] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd. + buffer[8] = REG_16_8_MSB(adev->config.hdmi_video_input_cmd. total_vertical_active_lines); - buffer[9] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + buffer[9] = REG_16_8_LSB(adev->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. + buffer[10] = adev->config.hdmi_video_input_cmd.video_mode; + buffer[11] = adev->config.hdmi_video_input_cmd.nb_data_lane; + buffer[12] = adev->config.hdmi_video_input_cmd. nb_virtual_ch_command_mode; - buffer[13] = av8100_config->hdmi_video_input_cmd. + buffer[13] = adev->config.hdmi_video_input_cmd. nb_virtual_ch_video_mode; - buffer[14] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd. + buffer[14] = REG_16_8_MSB(adev->config.hdmi_video_input_cmd. TE_line_nb); - buffer[15] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + buffer[15] = REG_16_8_LSB(adev->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. + buffer[16] = adev->config.hdmi_video_input_cmd.TE_config; + buffer[17] = REG_32_8_MSB(adev->config.hdmi_video_input_cmd. master_clock_freq); - buffer[18] = REG_32_8_MMSB(av8100_config->hdmi_video_input_cmd. + buffer[18] = REG_32_8_MMSB(adev->config.hdmi_video_input_cmd. master_clock_freq); - buffer[19] = REG_32_8_MLSB(av8100_config->hdmi_video_input_cmd. + buffer[19] = REG_32_8_MLSB(adev->config.hdmi_video_input_cmd. master_clock_freq); - buffer[20] = REG_32_8_LSB(av8100_config->hdmi_video_input_cmd. + buffer[20] = REG_32_8_LSB(adev->config.hdmi_video_input_cmd. master_clock_freq); - buffer[21] = av8100_config->hdmi_video_input_cmd.ui_x4; + buffer[21] = adev->config.hdmi_video_input_cmd.ui_x4; *length = AV8100_COMMAND_VIDEO_INPUT_FORMAT_SIZE - 1; return 0; } -static int configuration_audio_input_get(char *buffer, - unsigned int *length) +static int configuration_audio_input_get(struct av8100_device *adev, + 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; + buffer[0] = adev->config.hdmi_audio_input_cmd.audio_input_if_format; + buffer[1] = adev->config.hdmi_audio_input_cmd.i2s_input_nb; + buffer[2] = adev->config.hdmi_audio_input_cmd.sample_audio_freq; + buffer[3] = adev->config.hdmi_audio_input_cmd.audio_word_lg; + buffer[4] = adev->config.hdmi_audio_input_cmd.audio_format; + buffer[5] = adev->config.hdmi_audio_input_cmd.audio_if_mode; + buffer[6] = adev->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) +static int configuration_video_output_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { - if (!av8100_config) - return AV8100_FAIL; - - buffer[0] = av8100_config->hdmi_video_output_cmd. + buffer[0] = adev->config.hdmi_video_output_cmd. video_output_cea_vesa; if (buffer[0] == AV8100_CUSTOM) { - buffer[1] = av8100_config->hdmi_video_output_cmd. + buffer[1] = adev->config.hdmi_video_output_cmd. vsync_polarity; - buffer[2] = av8100_config->hdmi_video_output_cmd. + buffer[2] = adev->config.hdmi_video_output_cmd. hsync_polarity; - buffer[3] = REG_16_8_MSB(av8100_config-> + buffer[3] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd.total_horizontal_pixel); - buffer[4] = REG_16_8_LSB(av8100_config-> + buffer[4] = REG_16_8_LSB(adev->config. hdmi_video_output_cmd.total_horizontal_pixel); - buffer[5] = REG_16_8_MSB(av8100_config-> + buffer[5] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd.total_horizontal_active_pixel); - buffer[6] = REG_16_8_LSB(av8100_config-> + buffer[6] = REG_16_8_LSB(adev->config. hdmi_video_output_cmd.total_horizontal_active_pixel); - buffer[7] = REG_16_8_MSB(av8100_config-> + buffer[7] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd.total_vertical_in_half_lines); - buffer[8] = REG_16_8_LSB(av8100_config-> + buffer[8] = REG_16_8_LSB(adev->config. hdmi_video_output_cmd.total_vertical_in_half_lines); - buffer[9] = REG_16_8_MSB(av8100_config-> + buffer[9] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd. total_vertical_active_in_half_lines); - buffer[10] = REG_16_8_LSB(av8100_config-> + buffer[10] = REG_16_8_LSB(adev->config. hdmi_video_output_cmd. total_vertical_active_in_half_lines); - buffer[11] = REG_16_8_MSB(av8100_config-> + buffer[11] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd.hsync_start_in_pixel); - buffer[12] = REG_16_8_LSB(av8100_config-> + buffer[12] = REG_16_8_LSB(adev->config. hdmi_video_output_cmd.hsync_start_in_pixel); - buffer[13] = REG_16_8_MSB(av8100_config-> + buffer[13] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd.hsync_length_in_pixel); - buffer[14] = REG_16_8_LSB(av8100_config-> + buffer[14] = REG_16_8_LSB(adev->config. hdmi_video_output_cmd.hsync_length_in_pixel); - buffer[15] = REG_16_8_MSB(av8100_config-> + buffer[15] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd.vsync_start_in_half_line); - buffer[16] = REG_16_8_LSB(av8100_config-> + buffer[16] = REG_16_8_LSB(adev->config. hdmi_video_output_cmd.vsync_start_in_half_line); - buffer[17] = REG_16_8_MSB(av8100_config-> + buffer[17] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd.vsync_length_in_half_line); - buffer[18] = REG_16_8_LSB(av8100_config-> + buffer[18] = REG_16_8_LSB(adev->config. hdmi_video_output_cmd.vsync_length_in_half_line); - buffer[19] = REG_16_8_MSB(av8100_config-> + buffer[19] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd.hor_video_start_pixel); - buffer[20] = REG_16_8_LSB(av8100_config-> + buffer[20] = REG_16_8_LSB(adev->config. hdmi_video_output_cmd.hor_video_start_pixel); - buffer[21] = REG_16_8_MSB(av8100_config-> + buffer[21] = REG_16_8_MSB(adev->config. hdmi_video_output_cmd.vert_video_start_pixel); - buffer[22] = REG_16_8_LSB(av8100_config-> + buffer[22] = REG_16_8_LSB(adev->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-> + buffer[23] = adev->config.hdmi_video_output_cmd.video_type; + buffer[24] = adev->config.hdmi_video_output_cmd.pixel_repeat; + buffer[25] = REG_32_8_MSB(adev->config. hdmi_video_output_cmd.pixel_clock_freq_Hz); - buffer[26] = REG_32_8_MMSB(av8100_config-> + buffer[26] = REG_32_8_MMSB(adev->config. hdmi_video_output_cmd.pixel_clock_freq_Hz); - buffer[27] = REG_32_8_MLSB(av8100_config-> + buffer[27] = REG_32_8_MLSB(adev->config. hdmi_video_output_cmd.pixel_clock_freq_Hz); - buffer[28] = REG_32_8_LSB(av8100_config-> + buffer[28] = REG_32_8_LSB(adev->config. hdmi_video_output_cmd.pixel_clock_freq_Hz); *length = AV8100_COMMAND_VIDEO_OUTPUT_FORMAT_SIZE - 1; @@ -1401,58 +1423,53 @@ static int configuration_video_output_get(char *buffer, return 0; } -static int configuration_video_scaling_get(char *buffer, - unsigned int *length) +static int configuration_video_scaling_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { - if (!av8100_config) - return AV8100_FAIL; - - buffer[0] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + buffer[0] = REG_16_8_MSB(adev->config.hdmi_video_scaling_cmd. h_start_in_pixel); - buffer[1] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + buffer[1] = REG_16_8_LSB(adev->config.hdmi_video_scaling_cmd. h_start_in_pixel); - buffer[2] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + buffer[2] = REG_16_8_MSB(adev->config.hdmi_video_scaling_cmd. h_stop_in_pixel); - buffer[3] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + buffer[3] = REG_16_8_LSB(adev->config.hdmi_video_scaling_cmd. h_stop_in_pixel); - buffer[4] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + buffer[4] = REG_16_8_MSB(adev->config.hdmi_video_scaling_cmd. v_start_in_line); - buffer[5] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + buffer[5] = REG_16_8_LSB(adev->config.hdmi_video_scaling_cmd. v_start_in_line); - buffer[6] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + buffer[6] = REG_16_8_MSB(adev->config.hdmi_video_scaling_cmd. v_stop_in_line); - buffer[7] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + buffer[7] = REG_16_8_LSB(adev->config.hdmi_video_scaling_cmd. v_stop_in_line); - buffer[8] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + buffer[8] = REG_16_8_MSB(adev->config.hdmi_video_scaling_cmd. h_start_out_pixel); - buffer[9] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd + buffer[9] = REG_16_8_LSB(adev->config.hdmi_video_scaling_cmd .h_start_out_pixel); - buffer[10] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + buffer[10] = REG_16_8_MSB(adev->config.hdmi_video_scaling_cmd. h_stop_out_pixel); - buffer[11] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + buffer[11] = REG_16_8_LSB(adev->config.hdmi_video_scaling_cmd. h_stop_out_pixel); - buffer[12] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + buffer[12] = REG_16_8_MSB(adev->config.hdmi_video_scaling_cmd. v_start_out_line); - buffer[13] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + buffer[13] = REG_16_8_LSB(adev->config.hdmi_video_scaling_cmd. v_start_out_line); - buffer[14] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + buffer[14] = REG_16_8_MSB(adev->config.hdmi_video_scaling_cmd. v_stop_out_line); - buffer[15] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + buffer[15] = REG_16_8_LSB(adev->config.hdmi_video_scaling_cmd. v_stop_out_line); *length = AV8100_COMMAND_VIDEO_SCALING_FORMAT_SIZE - 1; return 0; } -static int configuration_colorspace_conversion_get(char *buffer, - unsigned int *length) +static int configuration_colorspace_conversion_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { const struct color_conversion_cmd *hdmi_color_space_conversion_cmd; - if (!av8100_config) - return AV8100_FAIL; hdmi_color_space_conversion_cmd = - get_color_transform_cmd(av8100_config->color_transform); + get_color_transform_cmd(adev, adev->config.color_transform); buffer[0] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c0); buffer[1] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c0); @@ -1487,17 +1504,14 @@ static int configuration_colorspace_conversion_get(char *buffer, return 0; } -static int configuration_cec_message_write_get(char *buffer, - unsigned int *length) +static int configuration_cec_message_write_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { - if (!av8100_config) - return AV8100_FAIL; - - buffer[0] = av8100_config->hdmi_cec_message_write_cmd.buffer_length; - memcpy(&buffer[1], av8100_config->hdmi_cec_message_write_cmd.buffer, - av8100_config->hdmi_cec_message_write_cmd.buffer_length); + buffer[0] = adev->config.hdmi_cec_message_write_cmd.buffer_length; + memcpy(&buffer[1], adev->config.hdmi_cec_message_write_cmd.buffer, + adev->config.hdmi_cec_message_write_cmd.buffer_length); - *length = av8100_config->hdmi_cec_message_write_cmd.buffer_length + 1; + *length = adev->config.hdmi_cec_message_write_cmd.buffer_length + 1; return 0; } @@ -1505,123 +1519,101 @@ static int configuration_cec_message_write_get(char *buffer, 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; } -static int configuration_denc_get(char *buffer, - unsigned int *length) +static int configuration_denc_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { - if (!av8100_config) - return AV8100_FAIL; - - 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.enable; - buffer[3] = av8100_config->hdmi_denc_cmd.macrovision_enable; - buffer[4] = av8100_config->hdmi_denc_cmd.internal_generator; + buffer[0] = adev->config.hdmi_denc_cmd.cvbs_video_format; + buffer[1] = adev->config.hdmi_denc_cmd.standard_selection; + buffer[2] = adev->config.hdmi_denc_cmd.enable; + buffer[3] = adev->config.hdmi_denc_cmd.macrovision_enable; + buffer[4] = adev->config.hdmi_denc_cmd.internal_generator; *length = AV8100_COMMAND_DENC_SIZE - 1; return 0; } -static int configuration_hdmi_get(char *buffer, unsigned int *length) +static int configuration_hdmi_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { - if (!av8100_config) - return AV8100_FAIL; - - buffer[0] = av8100_config->hdmi_cmd.hdmi_mode; - buffer[1] = av8100_config->hdmi_cmd.hdmi_format; - buffer[2] = av8100_config->hdmi_cmd.dvi_format; + buffer[0] = adev->config.hdmi_cmd.hdmi_mode; + buffer[1] = adev->config.hdmi_cmd.hdmi_format; + buffer[2] = adev->config.hdmi_cmd.dvi_format; *length = AV8100_COMMAND_HDMI_SIZE - 1; return 0; } -static int configuration_hdcp_sendkey_get(char *buffer, - unsigned int *length) +static int configuration_hdcp_sendkey_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { - if (!av8100_config) - return AV8100_FAIL; + buffer[0] = adev->config.hdmi_hdcp_send_key_cmd.key_number; + memcpy(&buffer[1], adev->config.hdmi_hdcp_send_key_cmd.data, + adev->config.hdmi_hdcp_send_key_cmd.data_len); - buffer[0] = av8100_config->hdmi_hdcp_send_key_cmd.key_number; - memcpy(&buffer[1], av8100_config->hdmi_hdcp_send_key_cmd.data, - av8100_config->hdmi_hdcp_send_key_cmd.data_len); - - *length = av8100_config->hdmi_hdcp_send_key_cmd.data_len + 1; + *length = adev->config.hdmi_hdcp_send_key_cmd.data_len + 1; return 0; } -static int configuration_hdcp_management_get(char *buffer, - unsigned int *length) +static int configuration_hdcp_management_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { - if (!av8100_config) - return AV8100_FAIL; - - buffer[0] = av8100_config->hdmi_hdcp_management_format_cmd.req_type; - buffer[1] = av8100_config->hdmi_hdcp_management_format_cmd.encr_use; + buffer[0] = adev->config.hdmi_hdcp_management_format_cmd.req_type; + buffer[1] = adev->config.hdmi_hdcp_management_format_cmd.encr_use; *length = AV8100_COMMAND_HDCP_MANAGEMENT_SIZE - 1; return 0; } -static int configuration_infoframe_get(char *buffer, - unsigned int *length) +static int configuration_infoframe_get(struct av8100_device *adev, + 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, + buffer[0] = adev->config.hdmi_infoframes_cmd.type; + buffer[1] = adev->config.hdmi_infoframes_cmd.version; + buffer[2] = adev->config.hdmi_infoframes_cmd.length; + buffer[3] = adev->config.hdmi_infoframes_cmd.crc; + memcpy(&buffer[4], adev->config.hdmi_infoframes_cmd.data, HDMI_INFOFRAME_DATA_SIZE); - *length = av8100_config->hdmi_infoframes_cmd.length + 4; + *length = adev->config.hdmi_infoframes_cmd.length + 4; return 0; } -static int av8100_edid_section_readback_get(char *buffer, unsigned int *length) +static int av8100_edid_section_readback_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { - buffer[0] = av8100_config->hdmi_edid_section_readback_cmd.address; - buffer[1] = av8100_config->hdmi_edid_section_readback_cmd. + buffer[0] = adev->config.hdmi_edid_section_readback_cmd.address; + buffer[1] = adev->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) +static int configuration_pattern_generator_get(struct av8100_device *adev, + 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. + buffer[0] = adev->config.hdmi_pattern_generator_cmd.pattern_type; + buffer[1] = adev->config.hdmi_pattern_generator_cmd. pattern_video_format; - buffer[2] = av8100_config->hdmi_pattern_generator_cmd. + buffer[2] = adev->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) +static int configuration_fuse_aes_key_get(struct av8100_device *adev, + char *buffer, unsigned int *length) { - if (!av8100_config) - return AV8100_FAIL; - - buffer[0] = av8100_config->hdmi_fuse_aes_key_cmd.fuse_operation; - if (av8100_config->hdmi_fuse_aes_key_cmd.fuse_operation) { + buffer[0] = adev->config.hdmi_fuse_aes_key_cmd.fuse_operation; + if (adev->config.hdmi_fuse_aes_key_cmd.fuse_operation) { /* Write key command */ - memcpy(&buffer[1], av8100_config->hdmi_fuse_aes_key_cmd.key, + memcpy(&buffer[1], adev->config.hdmi_fuse_aes_key_cmd.key, HDMI_FUSE_AES_KEY_SIZE); *length = AV8100_COMMAND_FUSE_AES_KEY_SIZE - 1; @@ -1636,15 +1628,16 @@ static int get_command_return_first(struct i2c_client *i2c, enum av8100_command_type command_type) { int retval = 0; char val; + struct device *dev = &i2c->dev; retval = read_single_byte(i2c, AV8100_COMMAND_OFFSET, &val); if (retval) { - dev_dbg(av8100dev, "%s 1st ret failed\n", __func__); + dev_dbg(dev, "%s 1st ret failed\n", __func__); return retval; } if (val != (0x80 | command_type)) { - dev_dbg(av8100dev, "%s 1st ret wrong:%x\n", __func__, val); + dev_dbg(dev, "%s 1st ret wrong:%x\n", __func__, val); return -EFAULT; } @@ -1660,6 +1653,7 @@ static int get_command_return_data(struct i2c_client *i2c, int retval = 0; char val; int index = 0; + struct device *dev = &i2c->dev; if (buffer_length) *buffer_length = 0; @@ -1682,14 +1676,14 @@ static int get_command_return_data(struct i2c_client *i2c, goto get_command_return_data_fail2r; if (val) { - retval = AV8100_FAIL; + retval = -EFAULT; goto get_command_return_data_fail2v; } break; case AV8100_COMMAND_CEC_MESSAGE_READ_BACK: if ((buffer == NULL) || (buffer_length == NULL)) { - retval = AV8100_FAIL; + retval = -EINVAL; goto get_command_return_data_fail; } @@ -1698,17 +1692,17 @@ static int get_command_return_data(struct i2c_client *i2c, if (retval) goto get_command_return_data_fail; - dev_dbg(av8100dev, "cec buflen:%d\n", val); + dev_dbg(dev, "cec buflen:%d\n", val); *buffer_length = val; if (*buffer_length > HDMI_CEC_READ_MAXSIZE) { - dev_dbg(av8100dev, "CEC size too large %d\n", + dev_dbg(dev, "CEC size too large %d\n", *buffer_length); *buffer_length = HDMI_CEC_READ_MAXSIZE; } - dev_dbg(av8100dev, "return data: "); + dev_dbg(dev, "return data: "); /* Get the return buffer */ for (index = 0; index < *buffer_length; ++index) { @@ -1719,11 +1713,11 @@ static int get_command_return_data(struct i2c_client *i2c, goto get_command_return_data_fail; } else { *(buffer + index) = val; - dev_dbg(av8100dev, "%02x ", *(buffer + index)); + dev_dbg(dev, "%02x ", *(buffer + index)); } } - dev_dbg(av8100dev, "\n"); + dev_dbg(dev, "\n"); break; case AV8100_COMMAND_HDCP_MANAGEMENT: @@ -1747,7 +1741,7 @@ static int get_command_return_data(struct i2c_client *i2c, /* Ignore return data */ break; - dev_dbg(av8100dev, "req_type:%02x ", command_buffer[0]); + dev_dbg(dev, "req_type:%02x ", command_buffer[0]); /* Check if revoc list data is requested */ if (command_buffer[0] != @@ -1756,7 +1750,7 @@ static int get_command_return_data(struct i2c_client *i2c, break; } - dev_dbg(av8100dev, "return data: "); + dev_dbg(dev, "return data: "); /* Get the return buffer */ for (cnt = 0; cnt < HDMI_HDCP_MGMT_BKSV_SIZE; cnt++) { @@ -1767,7 +1761,7 @@ static int get_command_return_data(struct i2c_client *i2c, goto get_command_return_data_fail; } else { *(buffer + index) = val; - dev_dbg(av8100dev, "%02x ", *(buffer + index)); + dev_dbg(dev, "%02x ", *(buffer + index)); } index++; } @@ -1780,7 +1774,7 @@ static int get_command_return_data(struct i2c_client *i2c, goto get_command_return_data_fail; } else { *(buffer + index) = nrdev; - dev_dbg(av8100dev, "%02x ", *(buffer + index)); + dev_dbg(dev, "%02x ", *(buffer + index)); } index++; @@ -1800,7 +1794,7 @@ static int get_command_return_data(struct i2c_client *i2c, goto get_command_return_data_fail; } else { *(buffer + index) = val; - dev_dbg(av8100dev, "%02x ", + dev_dbg(dev, "%02x ", *(buffer + index)); } index++; @@ -1818,7 +1812,7 @@ static int get_command_return_data(struct i2c_client *i2c, goto get_command_return_data_fail; } else { *(buffer + index) = val; - dev_dbg(av8100dev, "%02x ", *(buffer + index)); + dev_dbg(dev, "%02x ", *(buffer + index)); } index++; } @@ -1826,20 +1820,20 @@ static int get_command_return_data(struct i2c_client *i2c, hdcp_management_end: *buffer_length = index; - dev_dbg(av8100dev, "\n"); + dev_dbg(dev, "\n"); } break; case AV8100_COMMAND_EDID_SECTION_READBACK: if ((buffer == NULL) || (buffer_length == NULL)) { - retval = AV8100_FAIL; + retval = -EINVAL; goto get_command_return_data_fail; } /* Return buffer length is fixed */ *buffer_length = HDMI_EDIDREAD_SIZE; - dev_dbg(av8100dev, "return data: "); + dev_dbg(dev, "return data: "); /* Get the return buffer */ for (index = 0; index < *buffer_length; ++index) { @@ -1850,16 +1844,16 @@ hdcp_management_end: goto get_command_return_data_fail; } else { *(buffer + index) = val; - dev_dbg(av8100dev, "%02x ", *(buffer + index)); + dev_dbg(dev, "%02x ", *(buffer + index)); } } - dev_dbg(av8100dev, "\n"); + dev_dbg(dev, "\n"); break; case AV8100_COMMAND_FUSE_AES_KEY: if ((buffer == NULL) || (buffer_length == NULL)) { - retval = AV8100_FAIL; + retval = -EINVAL; goto get_command_return_data_fail; } @@ -1872,7 +1866,7 @@ hdcp_management_end: /* Check the second return byte */ if (val) { - retval = AV8100_FAIL; + retval = -EFAULT; goto get_command_return_data_fail2v; } @@ -1886,7 +1880,7 @@ hdcp_management_end: goto get_command_return_data_fail; *buffer = val; - dev_dbg(av8100dev, "CRC:%02x ", val); + dev_dbg(dev, "CRC:%02x ", val); /* Get programmed status */ retval = read_single_byte(i2c, @@ -1896,13 +1890,13 @@ hdcp_management_end: *(buffer + 1) = val; - dev_dbg(av8100dev, "programmed:%02x ", val); + dev_dbg(dev, "programmed:%02x ", val); break; case AV8100_COMMAND_HDCP_SENDKEY: if ((command_buffer[0] == HDMI_LOADAES_END_BLK_NR) && ((buffer == NULL) || (buffer_length == NULL))) { - retval = AV8100_FAIL; + retval = -EINVAL; goto get_command_return_data_fail; } @@ -1913,7 +1907,7 @@ hdcp_management_end: goto get_command_return_data_fail2r; if (val) { - retval = AV8100_FAIL; + retval = -EFAULT; goto get_command_return_data_fail2v; } @@ -1921,13 +1915,13 @@ hdcp_management_end: /* Return CRC32 if last AES block */ int cnt; - dev_dbg(av8100dev, "CRC32:"); + dev_dbg(dev, "CRC32:"); for (cnt = 0; cnt < HDMI_CRC32_SIZE; cnt++) { if (read_single_byte(i2c, AV8100_CRC32_OFFSET + cnt, &val)) goto get_command_return_data_fail; *(buffer + cnt) = val; - dev_dbg(av8100dev, "%02x", val); + dev_dbg(dev, "%02x", val); } *buffer_length = HDMI_CRC32_SIZE; @@ -1935,53 +1929,53 @@ hdcp_management_end: break; default: - retval = AV8100_INVALID_COMMAND; + retval = -EFAULT; break; } return retval; get_command_return_data_fail2r: - dev_dbg(av8100dev, "%s Reading 2nd return byte failed\n", __func__); + dev_dbg(dev, "%s Reading 2nd return byte failed\n", __func__); return retval; get_command_return_data_fail2v: - dev_dbg(av8100dev, "%s 2nd return byte is wrong:%x\n", __func__, val); + dev_dbg(dev, "%s 2nd return byte is wrong:%x\n", __func__, val); return retval; get_command_return_data_fail: - dev_dbg(av8100dev, "%s FAIL\n", __func__); + dev_dbg(dev, "%s FAIL\n", __func__); return retval; } -static int av8100_powerup1(void) +static int av8100_powerup1(struct av8100_device *adev) { int retval; - struct av8100_platform_data *pdata = av8100dev->platform_data; + struct av8100_platform_data *pdata = adev->dev->platform_data; /* Regulator enable */ - if ((av8100_globals->regulator_pwr) && - (av8100_globals->regulator_requested == false)) { - retval = regulator_enable(av8100_globals->regulator_pwr); + if ((adev->params.regulator_pwr) && + (adev->params.regulator_requested == false)) { + retval = regulator_enable(adev->params.regulator_pwr); if (retval < 0) { - dev_warn(av8100dev, "%s: regulator_enable failed\n", + dev_warn(adev->dev, "%s: regulator_enable failed\n", __func__); return retval; } - dev_dbg(av8100dev, "regulator_enable ok\n"); - av8100_globals->regulator_requested = true; + dev_dbg(adev->dev, "regulator_enable ok\n"); + adev->params.regulator_requested = true; } /* Reset av8100 */ gpio_set_value(pdata->reset, 1); /* Need to wait before proceeding */ - msleep(AV8100_WAITTIME_1MS); + mdelay(AV8100_WAITTIME_1MS); - av8100_set_state(AV8100_OPMODE_STANDBY); + av8100_set_state(adev, AV8100_OPMODE_STANDBY); if (pdata->alt_powerupseq) { - dev_dbg(av8100dev, "powerup seq alt\n"); + dev_dbg(adev->dev, "powerup seq alt\n"); retval = av8100_5V_w(0, 0, AV8100_ON_TIME); if (retval) { - dev_err(av8100dev, "%s reg_wr err 1\n", __func__); + dev_err(adev->dev, "%s reg_wr err 1\n", __func__); goto av8100_powerup1_err; } @@ -1993,7 +1987,7 @@ static int av8100_powerup1(void) AV8100_STANDBY_PENDING_INTERRUPT_ONI_LOW, AV8100_STANDBY_PENDING_INTERRUPT_BPDIG_HIGH); if (retval) { - dev_err(av8100dev, "%s reg_wr err 2\n", __func__); + dev_err(adev->dev, "%s reg_wr err 2\n", __func__); goto av8100_powerup1_err; } @@ -2002,20 +1996,20 @@ static int av8100_powerup1(void) retval = av8100_reg_stby_w(AV8100_STANDBY_CPD_LOW, AV8100_STANDBY_STBY_HIGH, pdata->mclk_freq); if (retval) { - dev_err(av8100dev, "%s reg_wr err 3\n", __func__); + dev_err(adev->dev, "%s reg_wr err 3\n", __func__); goto av8100_powerup1_err; } - msleep(AV8100_WAITTIME_1MS); + mdelay(AV8100_WAITTIME_1MS); retval = av8100_reg_stby_w(AV8100_STANDBY_CPD_LOW, AV8100_STANDBY_STBY_LOW, pdata->mclk_freq); if (retval) { - dev_err(av8100dev, "%s reg_wr err 4\n", __func__); + dev_err(adev->dev, "%s reg_wr err 4\n", __func__); goto av8100_powerup1_err; } - msleep(AV8100_WAITTIME_1MS); + mdelay(AV8100_WAITTIME_1MS); retval = av8100_reg_stby_pend_int_w( AV8100_STANDBY_PENDING_INTERRUPT_HPDI_LOW, @@ -2023,30 +2017,31 @@ static int av8100_powerup1(void) AV8100_STANDBY_PENDING_INTERRUPT_ONI_LOW, AV8100_STANDBY_PENDING_INTERRUPT_BPDIG_LOW); if (retval) { - dev_err(av8100dev, "%s reg_wr err 5\n", __func__); + dev_err(adev->dev, "%s reg_wr err 5\n", __func__); goto av8100_powerup1_err; } - msleep(AV8100_WAITTIME_1MS); + mdelay(AV8100_WAITTIME_1MS); } /* Get chip version */ - retval = av8100_reg_stby_pend_int_r(NULL, NULL, NULL, &chip_version); + retval = av8100_reg_stby_pend_int_r(NULL, NULL, NULL, + &adev->chip_version); if (retval) { - dev_err(av8100dev, "Failed to read chip version\n"); + dev_err(adev->dev, "Failed to read chip version\n"); goto av8100_powerup1_err; } - dev_info(av8100dev, "chip version:%d\n", chip_version); + dev_info(adev->dev, "chip version:%d\n", adev->chip_version); - switch (chip_version) { + switch (adev->chip_version) { case AV8100_CHIPVER_1: case AV8100_CHIPVER_2: break; default: - dev_err(av8100dev, "Unsupported chip version:%d\n", - chip_version); + dev_err(adev->dev, "Unsupported chip version:%d\n", + adev->chip_version); goto av8100_powerup1_err; break; } @@ -2058,23 +2053,23 @@ av8100_powerup1_err: return -EFAULT; } -static int av8100_powerup2(void) +static int av8100_powerup2(struct av8100_device *adev) { int retval; /* ON time & OFF time on 5v HDMI plug detect */ - retval = av8100_5V_w(av8100_globals->denc_off_time, - av8100_globals->hdmi_off_time, - av8100_globals->on_time); + retval = av8100_5V_w(adev->params.denc_off_time, + adev->params.hdmi_off_time, + adev->params.on_time); if (retval) { - dev_err(av8100dev, + dev_err(adev->dev, "Failed to write the value to av8100 register\n"); return retval; } - msleep(AV8100_WAITTIME_1MS); + mdelay(AV8100_WAITTIME_1MS); - av8100_set_state(AV8100_OPMODE_SCAN); + av8100_set_state(adev, AV8100_OPMODE_SCAN); return 0; } @@ -2083,19 +2078,21 @@ static int register_read_internal(u8 offset, u8 *value) { int retval = 0; struct i2c_client *i2c; + struct av8100_device *adev; - if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) - return -EINVAL; + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EFAULT; - if (!av8100_config) + if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; - i2c = av8100_config->client; + i2c = adev->config.client; /* Read from register */ retval = read_single_byte(i2c, offset, value); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to read the value from av8100 register\n"); return -EFAULT; } @@ -2107,16 +2104,18 @@ static int register_write_internal(u8 offset, u8 value) { int retval; struct i2c_client *i2c; + struct av8100_device *adev; - if (!av8100_config) - return -EINVAL; + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EFAULT; - i2c = av8100_config->client; + i2c = adev->config.client; /* Write to register */ retval = write_single_byte(i2c, offset, value); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to write the value to av8100 register\n"); return -EFAULT; } @@ -2127,12 +2126,19 @@ static int register_write_internal(u8 offset, u8 value) int av8100_powerscan(void) { int retval; - struct av8100_platform_data *pdata = av8100dev->platform_data; + struct av8100_device *adev; + struct av8100_platform_data *pdata; - dev_dbg(av8100dev, "%s\n", __func__); + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EFAULT; + + pdata = adev->dev->platform_data; + + dev_dbg(adev->dev, "%s\n", __func__); if (av8100_status_get().av8100_state > AV8100_OPMODE_SCAN) { - dev_dbg(av8100dev, "set to scan mode\n"); + dev_dbg(adev->dev, "set to scan mode\n"); av8100_disable_interrupt(); @@ -2140,32 +2146,32 @@ int av8100_powerscan(void) retval = av8100_reg_stby_w(AV8100_STANDBY_CPD_LOW, AV8100_STANDBY_STBY_LOW, pdata->mclk_freq); if (retval) { - dev_err(av8100dev, + dev_err(adev->dev, "Failed to write to av8100 register\n"); return retval; } /* Remove APE OPP requirement */ - if (av8100_globals->opp_requested) { + if (adev->params.opp_requested) { prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, - (char *)av8100_miscdev.name); + (char *)adev->miscdev.name); prcmu_qos_remove_requirement(PRCMU_QOS_DDR_OPP, - (char *)av8100_miscdev.name); - av8100_globals->opp_requested = false; + (char *)adev->miscdev.name); + adev->params.opp_requested = false; } /* Clock disable */ - if (av8100_globals->inputclk && - av8100_globals->inputclk_requested) { - clk_disable(av8100_globals->inputclk); - av8100_globals->inputclk_requested = false; + if (adev->params.inputclk && + adev->params.inputclk_requested) { + clk_disable(adev->params.inputclk); + adev->params.inputclk_requested = false; } - msleep(AV8100_WAITTIME_1MS); + mdelay(AV8100_WAITTIME_1MS); av8100_enable_interrupt(); - av8100_set_state(AV8100_OPMODE_SCAN); + av8100_set_state(adev, AV8100_OPMODE_SCAN); } return 0; @@ -2175,20 +2181,25 @@ EXPORT_SYMBOL(av8100_powerscan); int av8100_powerup(void) { int ret = 0; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EFAULT; if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) return -EINVAL; if (av8100_status_get().av8100_state < AV8100_OPMODE_STANDBY) { - ret = av8100_powerup1(); + ret = av8100_powerup1(adev); if (ret) { - dev_err(av8100dev, "av8100_powerup1 fail\n"); + dev_err(adev->dev, "av8100_powerup1 fail\n"); return -EFAULT; } } if (av8100_status_get().av8100_state < AV8100_OPMODE_SCAN) - ret = av8100_powerup2(); + ret = av8100_powerup2(adev); av8100_enable_interrupt(); @@ -2199,11 +2210,18 @@ EXPORT_SYMBOL(av8100_powerup); int av8100_powerdown(void) { int retval = 0; + struct av8100_device *adev; + struct av8100_platform_data *pdata; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EFAULT; - struct av8100_platform_data *pdata = av8100dev->platform_data; + pdata = adev->dev->platform_data; if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) goto av8100_powerdown_end; + av8100_disable_interrupt(); if (pdata->alt_powerupseq) { @@ -2214,39 +2232,39 @@ int av8100_powerdown(void) AV8100_STANDBY_PENDING_INTERRUPT_BPDIG_HIGH); if (retval) - dev_err(av8100dev, "%s reg_wr err\n", __func__); + dev_err(adev->dev, "%s reg_wr err\n", __func__); msleep(AV8100_WAITTIME_50MS); } /* Remove APE OPP requirement */ - if (av8100_globals->opp_requested) { + if (adev->params.opp_requested) { prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, - (char *)av8100_miscdev.name); + (char *)adev->miscdev.name); prcmu_qos_remove_requirement(PRCMU_QOS_DDR_OPP, - (char *)av8100_miscdev.name); - av8100_globals->opp_requested = false; + (char *)adev->miscdev.name); + adev->params.opp_requested = false; } /* Clock disable */ - if (av8100_globals->inputclk && av8100_globals->inputclk_requested) { - clk_disable(av8100_globals->inputclk); - av8100_globals->inputclk_requested = false; + if (adev->params.inputclk && adev->params.inputclk_requested) { + clk_disable(adev->params.inputclk); + adev->params.inputclk_requested = false; } /* Regulator disable */ - if ((av8100_globals->regulator_pwr) && - (av8100_globals->regulator_requested)) { - dev_dbg(av8100dev, "regulator_disable\n"); - regulator_disable(av8100_globals->regulator_pwr); - av8100_globals->regulator_requested = false; + if ((adev->params.regulator_pwr) && + (adev->params.regulator_requested)) { + dev_dbg(adev->dev, "regulator_disable\n"); + regulator_disable(adev->params.regulator_pwr); + adev->params.regulator_requested = false; } gpio_set_value(pdata->reset, 0); if (pdata->alt_powerupseq) - msleep(AV8100_WAITTIME_5MS); + mdelay(AV8100_WAITTIME_5MS); - av8100_set_state(AV8100_OPMODE_SHUTDOWN); + av8100_set_state(adev, AV8100_OPMODE_SHUTDOWN); av8100_powerdown_end: return retval; @@ -2271,66 +2289,85 @@ int av8100_download_firmware(char *fw_buf, int nbytes, u8 hld; u8 wa; u8 ra; - struct av8100_platform_data *pdata = av8100dev->platform_data; + struct av8100_platform_data *pdata; const struct firmware *fw_file; u8 *fw_buff; int fw_bytes; + struct av8100_device *adev; + struct av8100_status status; - if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) return -EINVAL; - if (!av8100_config) - return -EINVAL; + LOCK_AV8100_FWDL; + + status = av8100_status_get(); + if (status.av8100_state <= AV8100_OPMODE_SHUTDOWN) { + retval = -EINVAL; + goto av8100_download_firmware_err2; + } + + if (status.av8100_state >= AV8100_OPMODE_INIT) { + dev_dbg(adev->dev, "FW already ok\n"); + retval = 0; + goto av8100_download_firmware_err2; + } + + av8100_set_state(adev, AV8100_OPMODE_INIT); + + pdata = adev->dev->platform_data; /* Request firmware */ if (request_firmware(&fw_file, AV8100_FW_FILENAME, - av8100dev)) { - dev_err(av8100dev, "fw request failed\n"); - return -EFAULT; + adev->dev)) { + dev_err(adev->dev, "fw request failed\n"); + retval = -EFAULT; + goto av8100_download_firmware_err2; } /* Master clock timing, running */ retval = av8100_reg_stby_w(AV8100_STANDBY_CPD_LOW, AV8100_STANDBY_STBY_HIGH, pdata->mclk_freq); if (retval) { - dev_err(av8100dev, + dev_err(adev->dev, "Failed to write the value to av8100 register\n"); goto av8100_download_firmware_err; } - msleep(AV8100_WAITTIME_1MS); + mdelay(AV8100_WAITTIME_1MS); /* Clock enable */ - if (av8100_globals->inputclk && - av8100_globals->inputclk_requested == false) { - if (clk_enable(av8100_globals->inputclk)) { - dev_err(av8100dev, "inputclk en failed\n"); + if (adev->params.inputclk && + adev->params.inputclk_requested == false) { + if (clk_enable(adev->params.inputclk)) { + dev_err(adev->dev, "inputclk en failed\n"); retval = -EFAULT; goto av8100_download_firmware_err; } - av8100_globals->inputclk_requested = true; + adev->params.inputclk_requested = true; } /* Request 100% APE OPP */ - if (av8100_globals->opp_requested == false) { + if (adev->params.opp_requested == false) { if (prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, - (char *)av8100_miscdev.name, 100)) { - dev_err(av8100dev, "APE OPP 100 failed\n"); + (char *)adev->miscdev.name, 100)) { + dev_err(adev->dev, "APE OPP 100 failed\n"); retval = -EFAULT; goto av8100_download_firmware_err; } if (prcmu_qos_add_requirement(PRCMU_QOS_DDR_OPP, - (char *)av8100_miscdev.name, 100)) { - dev_err(av8100dev, "DDR OPP 100 failed\n"); + (char *)adev->miscdev.name, 100)) { + dev_err(adev->dev, "DDR OPP 100 failed\n"); prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, - (char *)av8100_miscdev.name); + (char *)adev->miscdev.name); retval = -EFAULT; goto av8100_download_firmware_err; } - av8100_globals->opp_requested = true; + adev->params.opp_requested = true; } msleep(AV8100_WAITTIME_10MS); @@ -2338,9 +2375,9 @@ int av8100_download_firmware(char *fw_buf, int nbytes, /* Prepare firmware data */ fw_bytes = fw_file->size; fw_buff = (u8 *)fw_file->data; - dev_dbg(av8100dev, "fw size:%d\n", fw_bytes); + dev_dbg(adev->dev, "fw size:%d\n", fw_bytes); - i2c = av8100_config->client; + i2c = adev->config.client; /* Enable firmware download */ retval = av8100_reg_gen_ctrl_w( @@ -2349,7 +2386,7 @@ int av8100_download_firmware(char *fw_buf, int nbytes, AV8100_GENERAL_CONTROL_WA_LOW, AV8100_GENERAL_CONTROL_RA_LOW); if (retval) { - dev_err(av8100dev, + dev_err(adev->dev, "Failed to write the value to av8100 register\n"); retval = -EFAULT; goto av8100_download_firmware_err; @@ -2357,12 +2394,12 @@ int av8100_download_firmware(char *fw_buf, int nbytes, retval = av8100_reg_gen_ctrl_r(&fdl, &hld, &wa, &ra); if (retval) { - dev_err(av8100dev, + dev_err(adev->dev, "Failed to read the value from av8100 register\n"); retval = -EFAULT; goto av8100_download_firmware_err; } else { - dev_dbg(av8100dev, "GENERAL_CONTROL_REG register fdl:%d " + dev_dbg(adev->dev, "GENERAL_CONTROL_REG register fdl:%d " "hld:%d wa:%d ra:%d\n", fdl, hld, wa, ra); } @@ -2376,14 +2413,14 @@ int av8100_download_firmware(char *fw_buf, int nbytes, AV8100_FIRMWARE_DOWNLOAD_ENTRY, fw_buff + size, increment); if (retval) { - dev_dbg(av8100dev, "Failed to download the " + dev_dbg(adev->dev, "Failed to download the " "av8100 firmware\n"); UNLOCK_AV8100_HW; retval = -EFAULT; goto av8100_download_firmware_err; } } else if (if_type == DSI_INTERFACE) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "DSI_INTERFACE is currently not supported\n"); UNLOCK_AV8100_HW; retval = -EINVAL; @@ -2400,7 +2437,7 @@ int av8100_download_firmware(char *fw_buf, int nbytes, retval = write_multi_byte(i2c, AV8100_FIRMWARE_DOWNLOAD_ENTRY, fw_buff + size, temp); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to download the av8100 firmware\n"); UNLOCK_AV8100_HW; retval = -EFAULT; @@ -2425,23 +2462,23 @@ int av8100_download_firmware(char *fw_buf, int nbytes, retval = av8100_reg_fw_dl_entry_r(&val); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to read the value from the av8100 register\n"); retval = -EFAULT; goto av8100_download_firmware_err; } - dev_dbg(av8100dev, "checksum:%x,val:%x\n", checksum, val); + dev_dbg(adev->dev, "checksum:%x,val:%x\n", checksum, val); if (checksum != val) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, ">Fw downloading.... FAIL checksum issue\n"); - dev_dbg(av8100dev, "checksum = %d\n", checksum); - dev_dbg(av8100dev, "checksum read: %d\n", val); + dev_dbg(adev->dev, "checksum = %d\n", checksum); + dev_dbg(adev->dev, "checksum read: %d\n", val); retval = -EFAULT; goto av8100_download_firmware_err; } else { - dev_dbg(av8100dev, ">Fw downloading.... success\n"); + dev_dbg(adev->dev, ">Fw downloading.... success\n"); } /* Set to idle mode */ @@ -2449,7 +2486,7 @@ int av8100_download_firmware(char *fw_buf, int nbytes, AV8100_GENERAL_CONTROL_HLD_LOW, AV8100_GENERAL_CONTROL_WA_LOW, AV8100_GENERAL_CONTROL_RA_LOW); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to write the value to the av8100 register\n"); retval = -EFAULT; goto av8100_download_firmware_err; @@ -2460,47 +2497,75 @@ int av8100_download_firmware(char *fw_buf, int nbytes, cnt_max = sizeof(waittime_retry); retval = av8100_reg_gen_status_r(NULL, NULL, NULL, &uc, NULL, NULL); - while ((retval == 0) && (uc != 0x1) && (cnt++ < cnt_max)) { - msleep(waittime_retry[cnt]); + while ((retval == 0) && (uc != 0x1) && (cnt < cnt_max)) { + mdelay(waittime_retry[cnt]); retval = av8100_reg_gen_status_r(NULL, NULL, NULL, &uc, NULL, NULL); + cnt++; } - dev_dbg(av8100dev, "av8100 fwdl cnt:%d\n", cnt); + dev_dbg(adev->dev, "av8100 fwdl cnt:%d\n", cnt); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to read the value from the av8100 register\n"); retval = -EFAULT; goto av8100_download_firmware_err; } if (uc != 0x1) - dev_dbg(av8100dev, "UC is not ready\n"); + dev_dbg(adev->dev, "UC is not ready\n"); release_firmware(fw_file); - av8100_set_state(AV8100_OPMODE_IDLE); + if (adev->chip_version != 1) { + /* Get cut version */ + retval = read_single_byte(i2c, AV8100_CUTVER_OFFSET, &val); + if (retval) { + dev_err(adev->dev, "Read cut ver failed\n"); + return retval; + } + switch (val) { + case 0: + dev_dbg(adev->dev, "Cut ver 0 (2.1)\n"); + break; + case 1: + dev_dbg(adev->dev, "Cut ver 1 (2.2)\n"); + break; + case 3: + dev_dbg(adev->dev, "Cut ver 3 (2.3)\n"); + break; + default: + dev_dbg(adev->dev, "Cut ver %d\n", val); + break; + } + } + + av8100_set_state(adev, AV8100_OPMODE_IDLE); + + UNLOCK_AV8100_FWDL; return 0; av8100_download_firmware_err: release_firmware(fw_file); /* Remove APE OPP requirement */ - if (av8100_globals->opp_requested) { + if (adev->params.opp_requested) { prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, - (char *)av8100_miscdev.name); + (char *)adev->miscdev.name); prcmu_qos_remove_requirement(PRCMU_QOS_DDR_OPP, - (char *)av8100_miscdev.name); - av8100_globals->opp_requested = false; + (char *)adev->miscdev.name); + adev->params.opp_requested = false; } /* Clock disable */ - if (av8100_globals->inputclk && av8100_globals->inputclk_requested) { - clk_disable(av8100_globals->inputclk); - av8100_globals->inputclk_requested = false; + if (adev->params.inputclk && adev->params.inputclk_requested) { + clk_disable(adev->params.inputclk); + adev->params.inputclk_requested = false; } +av8100_download_firmware_err2: + UNLOCK_AV8100_FWDL; return retval; } EXPORT_SYMBOL(av8100_download_firmware); @@ -2508,28 +2573,27 @@ EXPORT_SYMBOL(av8100_download_firmware); int av8100_disable_interrupt(void) { int retval; - struct i2c_client *i2c; u8 hpdm = 0; u8 cpdm = 0; + struct av8100_device *adev; - if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) return -EINVAL; - if (!av8100_globals || !av8100_config) + if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; - if (!av8100_globals->ints_enabled) + if (!adev->params.ints_enabled) return 0; - i2c = av8100_config->client; - retval = av8100_reg_stby_pend_int_w( AV8100_STANDBY_PENDING_INTERRUPT_HPDI_LOW, AV8100_STANDBY_PENDING_INTERRUPT_CPDI_LOW, AV8100_STANDBY_PENDING_INTERRUPT_ONI_LOW, AV8100_STANDBY_PENDING_INTERRUPT_BPDIG_LOW); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to write the value to av8100 register\n"); return -EFAULT; } @@ -2543,13 +2607,13 @@ int av8100_disable_interrupt(void) AV8100_GENERAL_INTERRUPT_MASK_UOVBM_LOW, AV8100_GENERAL_INTERRUPT_MASK_TEM_LOW); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to write the value to av8100 register\n"); return -EFAULT; } - hpdm = av8100_globals->hpdm; - cpdm = av8100_globals->cpdm; + hpdm = adev->params.hpdm; + cpdm = adev->params.cpdm; retval = av8100_reg_stby_int_mask_w( AV8100_STANDBY_INTERRUPT_MASK_HPDM_LOW, @@ -2557,14 +2621,14 @@ int av8100_disable_interrupt(void) AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT, AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to write the value to av8100 register\n"); return -EFAULT; } - av8100_globals->hpdm = hpdm; - av8100_globals->cpdm = cpdm; - av8100_globals->ints_enabled = false; + adev->params.hpdm = hpdm; + adev->params.cpdm = cpdm; + adev->params.ints_enabled = false; return 0; } @@ -2573,26 +2637,25 @@ EXPORT_SYMBOL(av8100_disable_interrupt); int av8100_enable_interrupt(void) { int retval; - struct i2c_client *i2c; + struct av8100_device *adev; - if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) return -EINVAL; - if (!av8100_globals || !av8100_config) + if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; - if (av8100_globals->ints_enabled) + if (adev->params.ints_enabled) return 0; - i2c = av8100_config->client; - retval = av8100_reg_stby_pend_int_w( AV8100_STANDBY_PENDING_INTERRUPT_HPDI_LOW, AV8100_STANDBY_PENDING_INTERRUPT_CPDI_LOW, AV8100_STANDBY_PENDING_INTERRUPT_ONI_LOW, AV8100_STANDBY_PENDING_INTERRUPT_BPDIG_LOW); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to write the value to av8100 register\n"); return -EFAULT; } @@ -2601,28 +2664,28 @@ int av8100_enable_interrupt(void) AV8100_GENERAL_INTERRUPT_MASK_EOCM_LOW, AV8100_GENERAL_INTERRUPT_MASK_VSIM_LOW, AV8100_GENERAL_INTERRUPT_MASK_VSOM_LOW, - av8100_globals->cecm, - av8100_globals->hdcpm, - AV8100_GENERAL_INTERRUPT_MASK_UOVBM_LOW, + adev->params.cecm, + adev->params.hdcpm, + adev->params.uovbm, AV8100_GENERAL_INTERRUPT_MASK_TEM_LOW); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to write the value to av8100 register\n"); return -EFAULT; } retval = av8100_reg_stby_int_mask_w( - av8100_globals->hpdm, - av8100_globals->cpdm, + adev->params.hpdm, + adev->params.cpdm, AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT, AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to write the value to av8100 register\n"); return -EFAULT; } - av8100_globals->ints_enabled = true; + adev->params.ints_enabled = true; return 0; } @@ -2654,6 +2717,11 @@ static int av8100_5V_w(u8 denc_off, u8 hdmi_off, u8 on) { u8 val; int retval; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; @@ -2663,7 +2731,7 @@ static int av8100_5V_w(u8 denc_off, u8 hdmi_off, u8 on) /* Set register value. * chip_version == 1 have one common off time * chip_version > 1 support different off time for hdmi and tvout. */ - if (chip_version == 1) + if (adev->chip_version == 1) val = AV8100_HDMI_5_VOLT_TIME_OFF_TIME(hdmi_off) | AV8100_HDMI_5_VOLT_TIME_ON_TIME(on); else @@ -2682,6 +2750,11 @@ static int av8100_5V_w(u8 denc_off, u8 hdmi_off, u8 on) int av8100_reg_hdmi_5_volt_time_w(u8 denc_off, u8 hdmi_off, u8 on) { int retval; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; @@ -2689,12 +2762,12 @@ int av8100_reg_hdmi_5_volt_time_w(u8 denc_off, u8 hdmi_off, u8 on) retval = av8100_5V_w(denc_off, hdmi_off, on); /* Set vars */ - if (chip_version > 1) - av8100_globals->denc_off_time = denc_off; + if (adev->chip_version > 1) + adev->params.denc_off_time = denc_off; - av8100_globals->hdmi_off_time = hdmi_off; + adev->params.hdmi_off_time = hdmi_off; if (on) - av8100_globals->on_time = on; + adev->params.on_time = on; return retval; } @@ -2705,6 +2778,11 @@ int av8100_reg_stby_int_mask_w( { int retval; u8 val; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; @@ -2720,8 +2798,8 @@ int av8100_reg_stby_int_mask_w( /* Write to register */ retval = register_write_internal(AV8100_STANDBY_INTERRUPT_MASK, val); - av8100_globals->hpdm = hpdm; - av8100_globals->cpdm = cpdm; + adev->params.hpdm = hpdm; + adev->params.cpdm = cpdm; UNLOCK_AV8100_HW; return retval; @@ -2886,23 +2964,23 @@ int av8100_reg_w( { int retval = 0; struct i2c_client *i2c; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; LOCK_AV8100_HW; - if (!av8100_config) { - UNLOCK_AV8100_HW; - return -EINVAL; - } - - i2c = av8100_config->client; + i2c = adev->config.client; /* Write to register */ retval = write_single_byte(i2c, offset, value); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to write the value to av8100 register\n"); UNLOCK_AV8100_HW; return -EFAULT; @@ -2949,6 +3027,11 @@ int av8100_reg_hdmi_5_volt_time_r( { int retval; u8 val; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; @@ -2959,7 +3042,7 @@ int av8100_reg_hdmi_5_volt_time_r( retval = register_read_internal(AV8100_HDMI_5_VOLT_TIME, &val); /* Set return params */ - if (chip_version == 1) { + if (adev->chip_version == 1) { if (denc_off_time) *denc_off_time = 0; if (hdmi_off_time) @@ -3264,23 +3347,23 @@ int av8100_reg_r( { int retval = 0; struct i2c_client *i2c; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; LOCK_AV8100_HW; - if (!av8100_config) { - retval = AV8100_FAIL; - goto av8100_register_read_out; - } - - i2c = av8100_config->client; + i2c = adev->config.client; /* Read from register */ retval = read_single_byte(i2c, offset, value); if (retval) { - dev_dbg(av8100dev, + dev_dbg(adev->dev, "Failed to read the value from av8100 register\n"); retval = -EFAULT; goto av8100_register_read_out; @@ -3295,104 +3378,107 @@ EXPORT_SYMBOL(av8100_reg_r); int av8100_conf_get(enum av8100_command_type command_type, union av8100_configuration *config) { - if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) return -EINVAL; - if (!av8100_config || !config) - return AV8100_FAIL; + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; /* 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, + &adev->config.hdmi_video_input_cmd, sizeof(struct av8100_video_input_format_cmd)); break; case AV8100_COMMAND_AUDIO_INPUT_FORMAT: memcpy(&config->audio_input_format, - &av8100_config->hdmi_audio_input_cmd, + &adev->config.hdmi_audio_input_cmd, sizeof(struct av8100_audio_input_format_cmd)); break; case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT: memcpy(&config->video_output_format, - &av8100_config->hdmi_video_output_cmd, + &adev->config.hdmi_video_output_cmd, sizeof(struct av8100_video_output_format_cmd)); break; case AV8100_COMMAND_VIDEO_SCALING_FORMAT: memcpy(&config->video_scaling_format, - &av8100_config->hdmi_video_scaling_cmd, + &adev->config.hdmi_video_scaling_cmd, sizeof(struct av8100_video_scaling_format_cmd)); break; case AV8100_COMMAND_COLORSPACECONVERSION: - config->color_transform = av8100_config->color_transform; + config->color_transform = adev->config.color_transform; break; case AV8100_COMMAND_CEC_MESSAGE_WRITE: memcpy(&config->cec_message_write_format, - &av8100_config->hdmi_cec_message_write_cmd, + &adev->config.hdmi_cec_message_write_cmd, sizeof(struct av8100_cec_message_write_format_cmd)); break; case AV8100_COMMAND_CEC_MESSAGE_READ_BACK: memcpy(&config->cec_message_read_back_format, - &av8100_config->hdmi_cec_message_read_back_cmd, + &adev->config.hdmi_cec_message_read_back_cmd, sizeof(struct av8100_cec_message_read_back_format_cmd)); break; case AV8100_COMMAND_DENC: - memcpy(&config->denc_format, &av8100_config->hdmi_denc_cmd, + memcpy(&config->denc_format, &adev->config.hdmi_denc_cmd, sizeof(struct av8100_denc_format_cmd)); break; case AV8100_COMMAND_HDMI: - memcpy(&config->hdmi_format, &av8100_config->hdmi_cmd, + memcpy(&config->hdmi_format, &adev->config.hdmi_cmd, sizeof(struct av8100_hdmi_cmd)); break; case AV8100_COMMAND_HDCP_SENDKEY: memcpy(&config->hdcp_send_key_format, - &av8100_config->hdmi_hdcp_send_key_cmd, + &adev->config.hdmi_hdcp_send_key_cmd, sizeof(struct av8100_hdcp_send_key_format_cmd)); break; case AV8100_COMMAND_HDCP_MANAGEMENT: memcpy(&config->hdcp_management_format, - &av8100_config->hdmi_hdcp_management_format_cmd, + &adev->config.hdmi_hdcp_management_format_cmd, sizeof(struct av8100_hdcp_management_format_cmd)); break; case AV8100_COMMAND_INFOFRAMES: memcpy(&config->infoframes_format, - &av8100_config->hdmi_infoframes_cmd, + &adev->config.hdmi_infoframes_cmd, sizeof(struct av8100_infoframes_format_cmd)); break; case AV8100_COMMAND_EDID_SECTION_READBACK: memcpy(&config->edid_section_readback_format, - &av8100_config->hdmi_edid_section_readback_cmd, + &adev->config.hdmi_edid_section_readback_cmd, sizeof(struct av8100_edid_section_readback_format_cmd)); break; case AV8100_COMMAND_PATTERNGENERATOR: memcpy(&config->pattern_generator_format, - &av8100_config->hdmi_pattern_generator_cmd, + &adev->config.hdmi_pattern_generator_cmd, sizeof(struct av8100_pattern_generator_format_cmd)); break; case AV8100_COMMAND_FUSE_AES_KEY: memcpy(&config->fuse_aes_key_format, - &av8100_config->hdmi_fuse_aes_key_cmd, + &adev->config.hdmi_fuse_aes_key_cmd, sizeof(struct av8100_fuse_aes_key_format_cmd)); break; default: - return AV8100_FAIL; + return -EINVAL; break; } @@ -3403,105 +3489,108 @@ EXPORT_SYMBOL(av8100_conf_get); int av8100_conf_prep(enum av8100_command_type command_type, union av8100_configuration *config) { - if (!av8100_config || !config) - return AV8100_FAIL; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!config || !adev) + return -EINVAL; /* 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, + memcpy(&adev->config.hdmi_video_input_cmd, &config->video_input_format, sizeof(struct av8100_video_input_format_cmd)); break; case AV8100_COMMAND_AUDIO_INPUT_FORMAT: - memcpy(&av8100_config->hdmi_audio_input_cmd, + memcpy(&adev->config.hdmi_audio_input_cmd, &config->audio_input_format, sizeof(struct av8100_audio_input_format_cmd)); break; case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT: - memcpy(&av8100_config->hdmi_video_output_cmd, + memcpy(&adev->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-> + av8100_config_video_output_dep(adev->config. hdmi_video_output_cmd.video_output_cea_vesa); break; case AV8100_COMMAND_VIDEO_SCALING_FORMAT: - memcpy(&av8100_config->hdmi_video_scaling_cmd, + memcpy(&adev->config.hdmi_video_scaling_cmd, &config->video_scaling_format, sizeof(struct av8100_video_scaling_format_cmd)); break; case AV8100_COMMAND_COLORSPACECONVERSION: - av8100_config->color_transform = config->color_transform; + adev->config.color_transform = config->color_transform; break; case AV8100_COMMAND_CEC_MESSAGE_WRITE: - memcpy(&av8100_config->hdmi_cec_message_write_cmd, + memcpy(&adev->config.hdmi_cec_message_write_cmd, &config->cec_message_write_format, sizeof(struct av8100_cec_message_write_format_cmd)); break; case AV8100_COMMAND_CEC_MESSAGE_READ_BACK: - memcpy(&av8100_config->hdmi_cec_message_read_back_cmd, + memcpy(&adev->config.hdmi_cec_message_read_back_cmd, &config->cec_message_read_back_format, sizeof(struct av8100_cec_message_read_back_format_cmd)); break; case AV8100_COMMAND_DENC: - memcpy(&av8100_config->hdmi_denc_cmd, &config->denc_format, + memcpy(&adev->config.hdmi_denc_cmd, &config->denc_format, sizeof(struct av8100_denc_format_cmd)); break; case AV8100_COMMAND_HDMI: - memcpy(&av8100_config->hdmi_cmd, &config->hdmi_format, + memcpy(&adev->config.hdmi_cmd, &config->hdmi_format, sizeof(struct av8100_hdmi_cmd)); break; case AV8100_COMMAND_HDCP_SENDKEY: - memcpy(&av8100_config->hdmi_hdcp_send_key_cmd, + memcpy(&adev->config.hdmi_hdcp_send_key_cmd, &config->hdcp_send_key_format, sizeof(struct av8100_hdcp_send_key_format_cmd)); break; case AV8100_COMMAND_HDCP_MANAGEMENT: - memcpy(&av8100_config->hdmi_hdcp_management_format_cmd, + memcpy(&adev->config.hdmi_hdcp_management_format_cmd, &config->hdcp_management_format, sizeof(struct av8100_hdcp_management_format_cmd)); break; case AV8100_COMMAND_INFOFRAMES: - memcpy(&av8100_config->hdmi_infoframes_cmd, + memcpy(&adev->config.hdmi_infoframes_cmd, &config->infoframes_format, sizeof(struct av8100_infoframes_format_cmd)); break; case AV8100_COMMAND_EDID_SECTION_READBACK: - memcpy(&av8100_config->hdmi_edid_section_readback_cmd, + memcpy(&adev->config.hdmi_edid_section_readback_cmd, &config->edid_section_readback_format, sizeof(struct av8100_edid_section_readback_format_cmd)); break; case AV8100_COMMAND_PATTERNGENERATOR: - memcpy(&av8100_config->hdmi_pattern_generator_cmd, + memcpy(&adev->config.hdmi_pattern_generator_cmd, &config->pattern_generator_format, sizeof(struct av8100_pattern_generator_format_cmd)); break; case AV8100_COMMAND_FUSE_AES_KEY: - memcpy(&av8100_config->hdmi_fuse_aes_key_cmd, + memcpy(&adev->config.hdmi_fuse_aes_key_cmd, &config->fuse_aes_key_format, sizeof(struct av8100_fuse_aes_key_format_cmd)); break; default: - return AV8100_FAIL; + return -EINVAL; break; } @@ -3517,6 +3606,11 @@ int av8100_conf_w(enum av8100_command_type command_type, u8 cmd_buffer[AV8100_COMMAND_MAX_LENGTH]; u32 cmd_length = 0; struct i2c_client *i2c; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; @@ -3524,47 +3618,44 @@ int av8100_conf_w(enum av8100_command_type command_type, if (return_buffer_length) *return_buffer_length = 0; - if (!av8100_config) - return AV8100_FAIL; - - i2c = av8100_config->client; + i2c = adev->config.client; memset(&cmd_buffer, 0x00, AV8100_COMMAND_MAX_LENGTH); -#define PRNK_MODE(_m) dev_dbg(av8100dev, "cmd: " #_m "\n"); +#define PRNK_MODE(_m) dev_dbg(adev->dev, "cmd: " #_m "\n"); /* 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); + configuration_video_input_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_AUDIO_INPUT_FORMAT: PRNK_MODE(AV8100_COMMAND_AUDIO_INPUT_FORMAT); - configuration_audio_input_get(cmd_buffer, &cmd_length); + configuration_audio_input_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT: PRNK_MODE(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT); - configuration_video_output_get(cmd_buffer, &cmd_length); + configuration_video_output_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_VIDEO_SCALING_FORMAT: PRNK_MODE(AV8100_COMMAND_VIDEO_SCALING_FORMAT); - configuration_video_scaling_get(cmd_buffer, + configuration_video_scaling_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_COLORSPACECONVERSION: PRNK_MODE(AV8100_COMMAND_COLORSPACECONVERSION); - configuration_colorspace_conversion_get(cmd_buffer, + configuration_colorspace_conversion_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_CEC_MESSAGE_WRITE: PRNK_MODE(AV8100_COMMAND_CEC_MESSAGE_WRITE); - configuration_cec_message_write_get(cmd_buffer, + configuration_cec_message_write_get(adev, cmd_buffer, &cmd_length); break; @@ -3576,49 +3667,49 @@ int av8100_conf_w(enum av8100_command_type command_type, case AV8100_COMMAND_DENC: PRNK_MODE(AV8100_COMMAND_DENC); - configuration_denc_get(cmd_buffer, &cmd_length); + configuration_denc_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_HDMI: PRNK_MODE(AV8100_COMMAND_HDMI); - configuration_hdmi_get(cmd_buffer, &cmd_length); + configuration_hdmi_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_HDCP_SENDKEY: PRNK_MODE(AV8100_COMMAND_HDCP_SENDKEY); - configuration_hdcp_sendkey_get(cmd_buffer, &cmd_length); + configuration_hdcp_sendkey_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_HDCP_MANAGEMENT: PRNK_MODE(AV8100_COMMAND_HDCP_MANAGEMENT); - configuration_hdcp_management_get(cmd_buffer, + configuration_hdcp_management_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_INFOFRAMES: PRNK_MODE(AV8100_COMMAND_INFOFRAMES); - configuration_infoframe_get(cmd_buffer, &cmd_length); + configuration_infoframe_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_EDID_SECTION_READBACK: PRNK_MODE(AV8100_COMMAND_EDID_SECTION_READBACK); - av8100_edid_section_readback_get(cmd_buffer, &cmd_length); + av8100_edid_section_readback_get(adev, cmd_buffer, &cmd_length); break; case AV8100_COMMAND_PATTERNGENERATOR: PRNK_MODE(AV8100_COMMAND_PATTERNGENERATOR); - configuration_pattern_generator_get(cmd_buffer, + configuration_pattern_generator_get(adev, 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); + configuration_fuse_aes_key_get(adev, cmd_buffer, &cmd_length); break; default: - dev_dbg(av8100dev, "Invalid command type\n"); - retval = AV8100_INVALID_COMMAND; + dev_dbg(adev->dev, "Invalid command type\n"); + retval = -EFAULT; break; } @@ -3628,11 +3719,11 @@ int av8100_conf_w(enum av8100_command_type command_type, int cnt = 0; int cnt_max; - dev_dbg(av8100dev, "av8100_conf_w cmd_type:%02x length:%02x ", + dev_dbg(adev->dev, "av8100_conf_w cmd_type:%02x length:%02x ", command_type, cmd_length); - dev_dbg(av8100dev, "buffer: "); + dev_dbg(adev->dev, "buffer: "); while (cnt < cmd_length) { - dev_dbg(av8100dev, "%02x ", cmd_buffer[cnt]); + dev_dbg(adev->dev, "%02x ", cmd_buffer[cnt]); cnt++; } @@ -3654,15 +3745,16 @@ int av8100_conf_w(enum av8100_command_type command_type, /* Get the first return byte */ - msleep(AV8100_WAITTIME_1MS); + mdelay(AV8100_WAITTIME_1MS); cnt = 0; cnt_max = sizeof(waittime_retry); retval = get_command_return_first(i2c, command_type); - while (retval && (cnt++ < cnt_max)) { - msleep(waittime_retry[cnt]); + while (retval && (cnt < cnt_max)) { + mdelay(waittime_retry[cnt]); retval = get_command_return_first(i2c, command_type); + cnt++; } - dev_dbg(av8100dev, "first return cnt:%d\n", cnt); + dev_dbg(adev->dev, "first return cnt:%d\n", cnt); if (retval) { UNLOCK_AV8100_HW; @@ -3674,14 +3766,14 @@ int av8100_conf_w(enum av8100_command_type command_type, } else if (if_type == DSI_INTERFACE) { /* TODO */ } else { - retval = AV8100_INVALID_INTERFACE; - dev_dbg(av8100dev, "Invalid command type\n"); + retval = -EINVAL; + dev_dbg(adev->dev, "Invalid command type\n"); } if (command_type == AV8100_COMMAND_HDMI) { - g_av8100_status.hdmi_on = ((av8100_config->hdmi_cmd. + adev->status.hdmi_on = ((adev->config.hdmi_cmd. hdmi_mode == AV8100_HDMI_ON) && - (av8100_config->hdmi_cmd.hdmi_format == AV8100_HDMI)); + (adev->config.hdmi_cmd.hdmi_format == AV8100_HDMI)); } UNLOCK_AV8100_HW; @@ -3699,6 +3791,11 @@ int av8100_conf_w_raw(enum av8100_command_type command_type, struct i2c_client *i2c; int cnt; int cnt_max; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; if (av8100_status_get().av8100_state <= AV8100_OPMODE_SHUTDOWN) return -EINVAL; @@ -3708,12 +3805,7 @@ int av8100_conf_w_raw(enum av8100_command_type command_type, if (return_buffer_length) *return_buffer_length = 0; - if (!av8100_config) { - retval = AV8100_FAIL; - goto av8100_conf_w_raw_out; - } - - i2c = av8100_config->client; + i2c = adev->config.client; /* Write the command buffer */ retval = write_multi_byte(i2c, @@ -3729,15 +3821,16 @@ int av8100_conf_w_raw(enum av8100_command_type command_type, /* Get the first return byte */ - msleep(AV8100_WAITTIME_1MS); + mdelay(AV8100_WAITTIME_1MS); cnt = 0; cnt_max = sizeof(waittime_retry); retval = get_command_return_first(i2c, command_type); - while (retval && (cnt++ < cnt_max)) { - msleep(waittime_retry[cnt]); + while (retval && (cnt < cnt_max)) { + mdelay(waittime_retry[cnt]); retval = get_command_return_first(i2c, command_type); + cnt++; } - dev_dbg(av8100dev, "first return cnt:%d\n", cnt); + dev_dbg(adev->dev, "first return cnt:%d\n", cnt); if (retval) goto av8100_conf_w_raw_out; @@ -3752,7 +3845,14 @@ EXPORT_SYMBOL(av8100_conf_w_raw); struct av8100_status av8100_status_get(void) { - return g_av8100_status; + struct av8100_status status = {0}; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (adev) + return adev->status; + else + return status; } EXPORT_SYMBOL(av8100_status_get); @@ -3768,6 +3868,11 @@ enum av8100_output_CEA_VESA av8100_video_output_format_get(int xres, int hres_div = 1; long freq1; long freq2; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; /* * 720_576_I need a divider for hact and htot since @@ -3783,7 +3888,7 @@ enum av8100_output_CEA_VESA av8100_video_output_format_get(int xres, av8100_all_cea[index].htotale / av8100_all_cea[index].vtotale; - dev_dbg(av8100dev, "freq1:%ld freq2:%ld\n", freq1, freq2); + dev_dbg(adev->dev, "freq1:%ld freq2:%ld\n", freq1, freq2); if ((xres == av8100_all_cea[index].hactive / hres_div) && (yres == av8100_all_cea[index].vactive * yres_div) && (htot == av8100_all_cea[index].htotale / hres_div) && @@ -3795,7 +3900,7 @@ enum av8100_output_CEA_VESA av8100_video_output_format_get(int xres, } av8100_video_output_format_get_out: - dev_dbg(av8100dev, "av8100_video_output_format_get %d %d %d %d %d\n", + dev_dbg(adev->dev, "av8100_video_output_format_get %d %d %d %d %d\n", xres, yres, htot, vtot, index); return index; } @@ -3803,25 +3908,29 @@ EXPORT_SYMBOL(av8100_video_output_format_get); void av8100_hdmi_event_cb_set(void (*hdmi_ev_cb)(enum av8100_hdmi_event)) { - if (av8100_globals) - av8100_globals->hdmi_ev_cb = hdmi_ev_cb; + struct av8100_device *adev; + + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (adev) + adev->params.hdmi_ev_cb = hdmi_ev_cb; } EXPORT_SYMBOL(av8100_hdmi_event_cb_set); u8 av8100_ver_get(void) { - u8 ret; + struct av8100_device *adev; - LOCK_AV8100_HW; - ret = chip_version; - UNLOCK_AV8100_HW; + adev = devnr_to_adev(AV8100_DEVNR_DEFAULT); + if (!adev) + return -EINVAL; - return ret; + return adev->chip_version; } EXPORT_SYMBOL(av8100_ver_get); static const struct color_conversion_cmd *get_color_transform_cmd( - enum av8100_color_transform transform) + struct av8100_device *adev, + enum av8100_color_transform transform) { const struct color_conversion_cmd *result; @@ -3833,7 +3942,7 @@ static const struct color_conversion_cmd *get_color_transform_cmd( result = &col_trans_identity_clamp_yuv; break; case AV8100_COLOR_TRANSFORM_YUV_TO_RGB: - if (chip_version == AV8100_CHIPVER_1) + if (adev->chip_version == AV8100_CHIPVER_1) result = &col_trans_yuv_to_rgb_v1; else result = &col_trans_yuv_to_rgb_v2; @@ -3845,7 +3954,7 @@ static const struct color_conversion_cmd *get_color_transform_cmd( result = &col_trans_rgb_to_denc; break; default: - dev_warn(av8100dev, "Unknown color space transform\n"); + dev_warn(adev->dev, "Unknown color space transform\n"); result = &col_trans_identity; break; } @@ -3854,13 +3963,13 @@ static const struct color_conversion_cmd *get_color_transform_cmd( static int av8100_open(struct inode *inode, struct file *filp) { - dev_dbg(av8100dev, "av8100_open is called\n"); + pr_debug("%s\n", __func__); return 0; } static int av8100_release(struct inode *inode, struct file *filp) { - dev_dbg(av8100dev, "av8100_release is called\n"); + pr_debug("%s\n", __func__); return 0; } @@ -3870,50 +3979,83 @@ static long av8100_ioctl(struct file *file, return 0; } -static int __devinit av8100_probe(struct i2c_client *i2cClient, - const struct i2c_device_id *id) +int av8100_device_register(struct av8100_device *adev) { - int ret = 0; - struct av8100_platform_data *pdata = i2cClient->dev.platform_data; + adev->miscdev.minor = MISC_DYNAMIC_MINOR; + adev->miscdev.name = "av8100"; + adev->miscdev.fops = &av8100_fops; - av8100dev = &i2cClient->dev; + if (misc_register(&adev->miscdev)) { + pr_err("av8100 misc_register failed\n"); + return -EFAULT; + } + return 0; +} - dev_dbg(av8100dev, "%s\n", __func__); +int av8100_init_device(struct av8100_device *adev, struct device *dev) +{ + adev->dev = dev; - av8100_set_state(AV8100_OPMODE_UNDEFINED); + if (av8100_config_init(adev)) { + dev_info(dev, "av8100_config_init failed\n"); + return -EFAULT; + } - ret = av8100_config_init(); - if (ret) { - dev_info(av8100dev, "av8100_config_init failed\n"); - goto err; + if (av8100_params_init(adev)) { + dev_info(dev, "av8100_params_init failed\n"); + return -EFAULT; } + return 0; +} - ret = av8100_globals_init(); - if (ret) { - dev_info(av8100dev, "av8100_globals_init failed\n"); - goto err; +static int __devinit av8100_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) +{ + int ret = 0; + struct av8100_platform_data *pdata = i2c_client->dev.platform_data; + struct device *dev; + struct av8100_device *adev; + + dev = &i2c_client->dev; + + dev_dbg(dev, "%s\n", __func__); + + /* Allocate device data */ + adev = kzalloc(sizeof(struct av8100_device), GFP_KERNEL); + if (!adev) { + dev_info(dev, "%s: Alloc failure\n", __func__); + return -ENOMEM; } - if (!i2c_check_functionality(i2cClient->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_READ_WORD_DATA)) { + /* Add to list */ + list_add_tail(&adev->list, &av8100_device_list); + + av8100_device_register(adev); + + av8100_init_device(adev, dev); + + av8100_set_state(adev, AV8100_OPMODE_UNDEFINED); + + if (!i2c_check_functionality(i2c_client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_READ_WORD_DATA)) { ret = -ENODEV; - dev_info(av8100dev, "av8100 i2c_check_functionality failed\n"); + dev_info(dev, "av8100 i2c_check_functionality failed\n"); goto err; } - init_waitqueue_head(&av8100_event); + init_waitqueue_head(&adev->event); - av8100_config->client = i2cClient; - av8100_config->id = (struct i2c_device_id *) id; - i2c_set_clientdata(i2cClient, av8100_config); + adev->config.client = i2c_client; + adev->config.id = (struct i2c_device_id *) id; + i2c_set_clientdata(i2c_client, &adev->config); - kthread_run(av8100_thread, NULL, "av8100_thread"); + kthread_run(av8100_thread, adev, "av8100_thread"); ret = request_irq(pdata->irq, av8100_intr_handler, - IRQF_TRIGGER_RISING, "av8100", av8100_config); + IRQF_TRIGGER_RISING, "av8100", adev); if (ret) { - dev_err(av8100dev, "av8100_hw request_irq %d failed %d\n", + dev_err(dev, "av8100_hw request_irq %d failed %d\n", pdata->irq, ret); gpio_free(pdata->irq); goto err; @@ -3921,33 +4063,33 @@ static int __devinit av8100_probe(struct i2c_client *i2cClient, /* Get regulator resource */ if (pdata->regulator_pwr_id) { - av8100_globals->regulator_pwr = regulator_get(av8100dev, + adev->params.regulator_pwr = regulator_get(dev, pdata->regulator_pwr_id); - if (IS_ERR(av8100_globals->regulator_pwr)) { - ret = PTR_ERR(av8100_globals->regulator_pwr); - dev_warn(av8100dev, + if (IS_ERR(adev->params.regulator_pwr)) { + ret = PTR_ERR(adev->params.regulator_pwr); + dev_warn(dev, "%s: Failed to get regulator '%s'\n", __func__, pdata->regulator_pwr_id); - av8100_globals->regulator_pwr = NULL; + adev->params.regulator_pwr = NULL; return ret; } } /* Get clock resource */ if (pdata->inputclk_id) { - av8100_globals->inputclk = clk_get(NULL, pdata->inputclk_id); - if (IS_ERR(av8100_globals->inputclk)) { - av8100_globals->inputclk = NULL; - dev_warn(av8100dev, "%s: Failed to get clock '%s'\n", + adev->params.inputclk = clk_get(NULL, pdata->inputclk_id); + if (IS_ERR(adev->params.inputclk)) { + adev->params.inputclk = NULL; + dev_warn(dev, "%s: Failed to get clock '%s'\n", __func__, pdata->inputclk_id); } } - av8100_set_state(AV8100_OPMODE_SHUTDOWN); + av8100_set_state(adev, AV8100_OPMODE_SHUTDOWN); /* Obtain the chip version */ - if (av8100_powerup1()) { - dev_err(av8100dev, "av8100_powerup1 fail\n"); + if (av8100_powerup1(adev)) { + dev_err(adev->dev, "av8100_powerup1 fail\n"); return -EFAULT; } @@ -3957,44 +4099,44 @@ err: return ret; } -static int __devexit av8100_remove(struct i2c_client *i2cClient) +static int __devexit av8100_remove(struct i2c_client *i2c_client) { - dev_dbg(av8100dev, "%s\n", __func__); + struct av8100_device *adev; - av8100_config_exit(); - av8100_globals_exit(); - if (av8100_globals->inputclk) - clk_put(av8100_globals->inputclk); + adev = dev_to_adev(&i2c_client->dev); + if (!adev) + return -EFAULT; + + dev_dbg(adev->dev, "%s\n", __func__); + + if (adev->params.inputclk) + clk_put(adev->params.inputclk); /* Release regulator resource */ - if (av8100_globals->regulator_pwr) - regulator_put(av8100_globals->regulator_pwr); + if (adev->params.regulator_pwr) + regulator_put(adev->params.regulator_pwr); + + misc_deregister(&adev->miscdev); + + /* Remove from list */ + list_del(&adev->list); + + /* Free device data */ + kfree(adev); return 0; } int av8100_init(void) { - int ret; - pr_debug("%s\n", __func__); - ret = i2c_add_driver(&av8100_driver); - if (ret) { + if (i2c_add_driver(&av8100_driver)) { pr_err("av8100 i2c_add_driver failed\n"); - goto av8100_init_err; - } - - ret = misc_register(&av8100_miscdev); - if (ret) { - pr_err("av8100 misc_register failed\n"); - goto av8100_init_err; + return -EFAULT; } - return ret; - -av8100_init_err: - return ret; + return 0; } module_init(av8100_init); @@ -4002,7 +4144,6 @@ void av8100_exit(void) { pr_debug("%s\n", __func__); - misc_deregister(&av8100_miscdev); i2c_del_driver(&av8100_driver); } module_exit(av8100_exit); diff --git a/drivers/video/av8100/hdmi.c b/drivers/video/av8100/hdmi.c index 4e6baf59200..c926f65ac26 100644 --- a/drivers/video/av8100/hdmi.c +++ b/drivers/video/av8100/hdmi.c @@ -24,20 +24,30 @@ #include <linux/slab.h> #include <linux/sched.h> #include <linux/delay.h> +#include <linux/list.h> #define SYSFS_EVENT_FILENAME "evread" +#define HDMI_DEVNR_DEFAULT 0 DEFINE_MUTEX(hdmi_events_mutex); #define LOCK_HDMI_EVENTS mutex_lock(&hdmi_events_mutex) #define UNLOCK_HDMI_EVENTS mutex_unlock(&hdmi_events_mutex) #define EVENTS_MASK 0xFF -static int device_open; -static int events; -static int events_mask; -static bool events_received; -static wait_queue_head_t hdmi_event_wq; -struct device *hdmidev; +struct hdmi_device { + struct list_head list; + struct miscdevice miscdev; + struct device *dev; + struct hdmi_sysfs_data sysfs_data; + int events; + int events_mask; + wait_queue_head_t event_wq; + bool events_received; + int devnr; +}; + +/* List of devices */ +static LIST_HEAD(hdmi_device_list); static ssize_t store_storeastext(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); @@ -88,39 +98,43 @@ static ssize_t show_poweronoff(struct device *dev, static ssize_t store_evwakeup(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -static DEVICE_ATTR(storeastext, S_IWUSR, NULL, store_storeastext); -static DEVICE_ATTR(plugdeten, S_IWUSR, NULL, store_plugdeten); -static DEVICE_ATTR(edidread, S_IRUGO | S_IWUSR, show_edidread, store_edidread); -static DEVICE_ATTR(ceceven, S_IWUSR, NULL, store_ceceven); -static DEVICE_ATTR(cecread, S_IRUGO, show_cecread, NULL); -static DEVICE_ATTR(cecsend, S_IWUSR, NULL, store_cecsend); -static DEVICE_ATTR(infofrsend, S_IWUSR, NULL, store_infofrsend); -static DEVICE_ATTR(hdcpeven, S_IWUSR, NULL, store_hdcpeven); -static DEVICE_ATTR(hdcpchkaesotp, S_IRUGO, show_hdcpchkaesotp, NULL); -static DEVICE_ATTR(hdcpfuseaes, S_IRUGO | S_IWUSR, show_hdcpfuseaes, - store_hdcpfuseaes); -static DEVICE_ATTR(hdcploadaes, S_IRUGO | S_IWUSR, show_hdcploadaes, - store_hdcploadaes); -static DEVICE_ATTR(hdcpauthencr, S_IRUGO | S_IWUSR, show_hdcpauthencr, - store_hdcpauthencr); -static DEVICE_ATTR(hdcpstateget, S_IRUGO, show_hdcpstateget, NULL); -static DEVICE_ATTR(evread, S_IRUGO, show_evread, NULL); -static DEVICE_ATTR(evclr, S_IWUSR, NULL, store_evclr); -static DEVICE_ATTR(audiocfg, S_IWUSR, NULL, store_audiocfg); -static DEVICE_ATTR(plugstatus, S_IRUGO, show_plugstatus, NULL); -static DEVICE_ATTR(poweronoff, S_IRUGO | S_IWUSR, show_poweronoff, - store_poweronoff); -static DEVICE_ATTR(evwakeup, S_IWUSR, NULL, store_evwakeup); +static const struct device_attribute hdmi_sysfs_attrs[] = { + __ATTR(storeastext, S_IWUSR, NULL, store_storeastext), + __ATTR(plugdeten, S_IWUSR, NULL, store_plugdeten), + __ATTR(edidread, S_IRUGO | S_IWUSR, show_edidread, store_edidread), + __ATTR(ceceven, S_IWUSR, NULL, store_ceceven), + __ATTR(cecread, S_IRUGO, show_cecread, NULL), + __ATTR(cecsend, S_IWUSR, NULL, store_cecsend), + __ATTR(infofrsend, S_IWUSR, NULL, store_infofrsend), + __ATTR(hdcpeven, S_IWUSR, NULL, store_hdcpeven), + __ATTR(hdcpchkaesotp, S_IRUGO, show_hdcpchkaesotp, NULL), + __ATTR(hdcpfuseaes, S_IRUGO | S_IWUSR, show_hdcpfuseaes, + store_hdcpfuseaes), + __ATTR(hdcploadaes, S_IRUGO | S_IWUSR, show_hdcploadaes, + store_hdcploadaes), + __ATTR(hdcpauthencr, S_IRUGO | S_IWUSR, show_hdcpauthencr, + store_hdcpauthencr), + __ATTR(hdcpstateget, S_IRUGO, show_hdcpstateget, NULL), + __ATTR(evread, S_IRUGO, show_evread, NULL), + __ATTR(evclr, S_IWUSR, NULL, store_evclr), + __ATTR(audiocfg, S_IWUSR, NULL, store_audiocfg), + __ATTR(plugstatus, S_IRUGO, show_plugstatus, NULL), + __ATTR(poweronoff, S_IRUGO | S_IWUSR, show_poweronoff, + store_poweronoff), + __ATTR(evwakeup, S_IWUSR, NULL, store_evwakeup), + __ATTR_NULL +}; /* Hex to int conversion */ static unsigned int htoi(const char *ptr) { unsigned int value = 0; - char ch = *ptr; + char ch; if (!ptr) return 0; + ch = *ptr; if (isdigit(ch)) value = ch - '0'; else @@ -137,32 +151,67 @@ static unsigned int htoi(const char *ptr) return value; } -static int event_enable(bool enable, enum hdmi_event ev) +static struct hdmi_device *dev_to_hdev(struct device *dev) { - struct kobject *kobj = &hdmidev->kobj; + /* Get device from list of devices */ + struct list_head *element; + struct hdmi_device *hdmi_dev; + int cnt = 0; + + list_for_each(element, &hdmi_device_list) { + hdmi_dev = list_entry(element, struct hdmi_device, list); + if (hdmi_dev->dev == dev) + return hdmi_dev; + cnt++; + } + + return NULL; +} + +static struct hdmi_device *devnr_to_hdev(int devnr) +{ + /* Get device from list of devices */ + struct list_head *element; + struct hdmi_device *hdmi_dev; + int cnt = 0; + + list_for_each(element, &hdmi_device_list) { + hdmi_dev = list_entry(element, struct hdmi_device, list); + if (cnt == devnr) + return hdmi_dev; + cnt++; + } - dev_dbg(hdmidev, "enable_event %d %02x\n", enable, ev); + return NULL; +} + +static int event_enable(struct hdmi_device *hdev, bool enable, + enum hdmi_event ev) +{ + struct kobject *kobj = &hdev->dev->kobj; + + dev_dbg(hdev->dev, "enable_event %d %02x\n", enable, ev); if (enable) - events_mask |= ev; + hdev->events_mask |= ev; else - events_mask &= ~ev; + hdev->events_mask &= ~ev; - if (events & ev) { + if (hdev->events & ev) { /* Report pending event */ /* Wake up application waiting for event via call to poll() */ sysfs_notify(kobj, NULL, SYSFS_EVENT_FILENAME); LOCK_HDMI_EVENTS; - events_received = true; + hdev->events_received = true; UNLOCK_HDMI_EVENTS; - wake_up_interruptible(&hdmi_event_wq); + wake_up_interruptible(&hdev->event_wq); } return 0; } -static int plugdeten(struct plug_detect *pldet) +static int plugdeten(struct hdmi_device *hdev, struct plug_detect *pldet) { struct av8100_status status; u8 denc_off_time = 0; @@ -171,14 +220,14 @@ static int plugdeten(struct plug_detect *pldet) status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } - event_enable(pldet->hdmi_detect_enable != 0, + event_enable(hdev, pldet->hdmi_detect_enable != 0, HDMI_EVENT_HDMI_PLUGIN); - event_enable(pldet->hdmi_detect_enable != 0, + event_enable(hdev, pldet->hdmi_detect_enable != 0, HDMI_EVENT_HDMI_PLUGOUT); av8100_reg_hdmi_5_volt_time_r(&denc_off_time, NULL, NULL); @@ -189,7 +238,7 @@ static int plugdeten(struct plug_detect *pldet) pldet->on_time); if (retval) { - dev_err(hdmidev, "Failed to write the value to av8100 " + dev_err(hdev->dev, "Failed to write the value to av8100 " "register\n"); return -EFAULT; } @@ -197,7 +246,8 @@ static int plugdeten(struct plug_detect *pldet) return retval; } -static int edidread(struct edid_read *edidread, u8 *len, u8 *data) +static int edidread(struct hdmi_device *hdev, struct edid_read *edidread, + u8 *len, u8 *data) { union av8100_configuration config; struct av8100_status status; @@ -205,14 +255,14 @@ static int edidread(struct edid_read *edidread, u8 *len, u8 *data) status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } if (status.av8100_state < AV8100_OPMODE_INIT) { if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } } @@ -220,28 +270,29 @@ static int edidread(struct edid_read *edidread, u8 *len, u8 *data) config.edid_section_readback_format.address = edidread->address; config.edid_section_readback_format.block_number = edidread->block_nr; - dev_dbg(hdmidev, "addr:%0x blnr:%0x", + dev_dbg(hdev->dev, "addr:%0x blnr:%0x", config.edid_section_readback_format.address, config.edid_section_readback_format.block_number); if (av8100_conf_prep(AV8100_COMMAND_EDID_SECTION_READBACK, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_conf_w(AV8100_COMMAND_EDID_SECTION_READBACK, len, data, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } - dev_dbg(hdmidev, "len:%0x\n", *len); + dev_dbg(hdev->dev, "len:%0x\n", *len); return 0; } -static int cecread(u8 *src, u8 *dest, u8 *data_len, u8 *data) +static int cecread(struct hdmi_device *hdev, u8 *src, u8 *dest, u8 *data_len, + u8 *data) { union av8100_configuration config; struct av8100_status status; @@ -251,27 +302,27 @@ static int cecread(u8 *src, u8 *dest, u8 *data_len, u8 *data) status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } if (status.av8100_state < AV8100_OPMODE_INIT) { - if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } } if (av8100_conf_prep(AV8100_COMMAND_CEC_MESSAGE_READ_BACK, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_conf_w(AV8100_COMMAND_CEC_MESSAGE_READ_BACK, &buf_len, buff, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } @@ -287,30 +338,33 @@ static int cecread(u8 *src, u8 *dest, u8 *data_len, u8 *data) } /* CEC tx status can be set or read */ -static bool cec_tx_status(enum cec_tx_status_action action) +static bool cec_tx_status(struct hdmi_device *hdev, + enum cec_tx_status_action action) { static bool cec_tx_busy; switch (action) { case CEC_TX_SET_FREE: cec_tx_busy = false; - dev_dbg(hdmidev, "cec_tx_busy set:%d\n", cec_tx_busy); + dev_dbg(hdev->dev, "cec_tx_busy set:%d\n", cec_tx_busy); break; case CEC_TX_SET_BUSY: cec_tx_busy = true; - dev_dbg(hdmidev, "cec_tx_busy set:%d\n", cec_tx_busy); + dev_dbg(hdev->dev, "cec_tx_busy set:%d\n", cec_tx_busy); break; case CEC_TX_CHECK: default: - dev_dbg(hdmidev, "cec_tx_busy chk:%d\n", cec_tx_busy); + dev_dbg(hdev->dev, "cec_tx_busy chk:%d\n", cec_tx_busy); break; } return cec_tx_busy; } -static int cecsend(u8 src, u8 dest, u8 data_len, u8 *data) + +static int cecsend(struct hdmi_device *hdev, u8 src, u8 dest, u8 data_len, + u8 *data) { union av8100_configuration config; struct av8100_status status; @@ -319,14 +373,14 @@ static int cecsend(u8 src, u8 dest, u8 data_len, u8 *data) status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } if (status.av8100_state < AV8100_OPMODE_INIT) { if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } } @@ -338,34 +392,35 @@ static int cecsend(u8 src, u8 dest, u8 data_len, u8 *data) if (av8100_conf_prep(AV8100_COMMAND_CEC_MESSAGE_WRITE, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_enable_interrupt() != 0) { - dev_err(hdmidev, "av8100_ei FAIL\n"); + dev_err(hdev->dev, "av8100_ei FAIL\n"); return -EINVAL; } cnt = 0; - while ((cnt < CECTX_TRY) && cec_tx_status(CEC_TX_CHECK)) { + while ((cnt < CECTX_TRY) && cec_tx_status(hdev, CEC_TX_CHECK)) { /* Wait for pending CEC to be finished */ msleep(CECTX_WAITTIME); cnt++; } - dev_dbg(hdmidev, "cectxcnt:%d\n", cnt); + dev_dbg(hdev->dev, "cectxcnt:%d\n", cnt); if (av8100_conf_w(AV8100_COMMAND_CEC_MESSAGE_WRITE, NULL, NULL, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } - cec_tx_status(CEC_TX_SET_BUSY); + cec_tx_status(hdev, CEC_TX_SET_BUSY); return 0; } -static int infofrsend(u8 type, u8 version, u8 crc, u8 data_len, u8 *data) +static int infofrsend(struct hdmi_device *hdev, u8 type, u8 version, u8 crc, + u8 data_len, u8 *data) { union av8100_configuration config; struct av8100_status status; @@ -373,14 +428,14 @@ static int infofrsend(u8 type, u8 version, u8 crc, u8 data_len, u8 *data) status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } if (status.av8100_state < AV8100_OPMODE_INIT) { if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } } @@ -395,20 +450,20 @@ static int infofrsend(u8 type, u8 version, u8 crc, u8 data_len, u8 *data) memcpy(&config.infoframes_format.data, data, data_len); if (av8100_conf_prep(AV8100_COMMAND_INFOFRAMES, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_conf_w(AV8100_COMMAND_INFOFRAMES, NULL, NULL, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } return 0; } -static int hdcpchkaesotp(u8 *crc, u8 *progged) +static int hdcpchkaesotp(struct hdmi_device *hdev, u8 *crc, u8 *progged) { union av8100_configuration config; struct av8100_status status; @@ -418,7 +473,7 @@ static int hdcpchkaesotp(u8 *crc, u8 *progged) status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } @@ -426,7 +481,7 @@ static int hdcpchkaesotp(u8 *crc, u8 *progged) if (status.av8100_state < AV8100_OPMODE_INIT) { if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } } @@ -435,13 +490,13 @@ static int hdcpchkaesotp(u8 *crc, u8 *progged) memset(config.fuse_aes_key_format.key, 0, AV8100_FUSE_KEY_SIZE); if (av8100_conf_prep(AV8100_COMMAND_FUSE_AES_KEY, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_conf_w(AV8100_COMMAND_FUSE_AES_KEY, &buf_len, buf, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } @@ -453,7 +508,7 @@ static int hdcpchkaesotp(u8 *crc, u8 *progged) return 0; } -static int hdcpfuseaes(u8 *key, u8 crc, u8 *result) +static int hdcpfuseaes(struct hdmi_device *hdev, u8 *key, u8 crc, u8 *result) { union av8100_configuration config; struct av8100_status status; @@ -466,7 +521,7 @@ static int hdcpfuseaes(u8 *key, u8 crc, u8 *result) status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } @@ -474,7 +529,7 @@ static int hdcpfuseaes(u8 *key, u8 crc, u8 *result) if (status.av8100_state < AV8100_OPMODE_INIT) { if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } } @@ -483,18 +538,18 @@ static int hdcpfuseaes(u8 *key, u8 crc, u8 *result) memcpy(config.fuse_aes_key_format.key, key, AV8100_FUSE_KEY_SIZE); if (av8100_conf_prep(AV8100_COMMAND_FUSE_AES_KEY, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_conf_w(AV8100_COMMAND_FUSE_AES_KEY, &buf_len, buf, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } if (buf_len == 2) { - dev_dbg(hdmidev, "buf[0]:%02x buf[1]:%02x\n", buf[0], buf[1]); + dev_dbg(hdev->dev, "buf[0]:%02x buf[1]:%02x\n", buf[0], buf[1]); if ((crc == buf[0]) && (buf[1] == 1)) /* OK */ *result = HDMI_RESULT_OK; @@ -505,7 +560,8 @@ static int hdcpfuseaes(u8 *key, u8 crc, u8 *result) return 0; } -static int hdcploadaes(u8 block, u8 key_len, u8 *key, u8 *result, u8 *crc32) +static int hdcploadaes(struct hdmi_device *hdev, u8 block, u8 key_len, u8 *key, + u8 *result, u8 *crc32) { union av8100_configuration config; struct av8100_status status; @@ -515,19 +571,19 @@ static int hdcploadaes(u8 block, u8 key_len, u8 *key, u8 *result, u8 *crc32) /* Default not OK */ *result = HDMI_RESULT_NOT_OK; - dev_dbg(hdmidev, "%s block:%d\n", __func__, block); + dev_dbg(hdev->dev, "%s block:%d\n", __func__, block); status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } if (status.av8100_state < AV8100_OPMODE_INIT) { if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } } @@ -536,19 +592,19 @@ static int hdcploadaes(u8 block, u8 key_len, u8 *key, u8 *result, u8 *crc32) config.hdcp_send_key_format.data_len = key_len; memcpy(config.hdcp_send_key_format.data, key, key_len); if (av8100_conf_prep(AV8100_COMMAND_HDCP_SENDKEY, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_conf_w(AV8100_COMMAND_HDCP_SENDKEY, &buf_len, buf, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } if ((buf_len == CRC32_SIZE) && (crc32)) { memcpy(crc32, buf, CRC32_SIZE); - dev_dbg(hdmidev, "crc32:%02x%02x%02x%02x\n", + dev_dbg(hdev->dev, "crc32:%02x%02x%02x%02x\n", crc32[0], crc32[1], crc32[2], crc32[3]); } @@ -557,7 +613,8 @@ static int hdcploadaes(u8 block, u8 key_len, u8 *key, u8 *result, u8 *crc32) return 0; } -static int hdcpauthencr(u8 auth_type, u8 encr_type, u8 *len, u8 *data) +static int hdcpauthencr(struct hdmi_device *hdev, u8 auth_type, u8 encr_type, + u8 *len, u8 *data) { union av8100_configuration config; struct av8100_status status; @@ -565,14 +622,14 @@ static int hdcpauthencr(u8 auth_type, u8 encr_type, u8 *len, u8 *data) status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } if (status.av8100_state < AV8100_OPMODE_INIT) { if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } } @@ -614,61 +671,61 @@ static int hdcpauthencr(u8 auth_type, u8 encr_type, u8 *len, u8 *data) if (av8100_conf_prep(AV8100_COMMAND_HDCP_MANAGEMENT, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_conf_w(AV8100_COMMAND_HDCP_MANAGEMENT, len, data, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } return 0; } -static u8 events_read(void) +static u8 events_read(struct hdmi_device *hdev) { int ret; LOCK_HDMI_EVENTS; - ret = events; - dev_dbg(hdmidev, "%s %02x\n", __func__, events); + ret = hdev->events; + dev_dbg(hdev->dev, "%s %02x\n", __func__, hdev->events); UNLOCK_HDMI_EVENTS; return ret; } -static int events_clear(u8 ev) +static int events_clear(struct hdmi_device *hdev, u8 ev) { - dev_dbg(hdmidev, "%s %02x\n", __func__, ev); + dev_dbg(hdev->dev, "%s %02x\n", __func__, ev); LOCK_HDMI_EVENTS; - events &= ~ev & EVENTS_MASK; + hdev->events &= ~ev & EVENTS_MASK; UNLOCK_HDMI_EVENTS; return 0; } -static int event_wakeup(void) +static int event_wakeup(struct hdmi_device *hdev) { - struct kobject *kobj = &hdmidev->kobj; + struct kobject *kobj = &hdev->dev->kobj; - dev_dbg(hdmidev, "%s", __func__); + dev_dbg(hdev->dev, "%s", __func__); LOCK_HDMI_EVENTS; - events |= HDMI_EVENT_WAKEUP; - events_received = true; + hdev->events |= HDMI_EVENT_WAKEUP; + hdev->events_received = true; UNLOCK_HDMI_EVENTS; /* Wake up application waiting for event via call to poll() */ sysfs_notify(kobj, NULL, SYSFS_EVENT_FILENAME); - wake_up_interruptible(&hdmi_event_wq); + wake_up_interruptible(&hdev->event_wq); return 0; } -static int audiocfg(struct audio_cfg *cfg) +static int audiocfg(struct hdmi_device *hdev, struct audio_cfg *cfg) { union av8100_configuration config; struct av8100_status status; @@ -676,14 +733,14 @@ static int audiocfg(struct audio_cfg *cfg) status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_STANDBY) { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup failed\n"); + dev_err(hdev->dev, "av8100_powerup failed\n"); return -EINVAL; } } if (status.av8100_state < AV8100_OPMODE_INIT) { if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } } @@ -698,13 +755,13 @@ static int audiocfg(struct audio_cfg *cfg) if (av8100_conf_prep(AV8100_COMMAND_AUDIO_INPUT_FORMAT, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_conf_w(AV8100_COMMAND_AUDIO_INPUT_FORMAT, NULL, NULL, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } @@ -715,11 +772,12 @@ static int audiocfg(struct audio_cfg *cfg) static ssize_t store_storeastext(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); if ((count != HDMI_STOREASTEXT_BIN_SIZE) && (count != HDMI_STOREASTEXT_TEXT_SIZE) && @@ -727,17 +785,17 @@ static ssize_t store_storeastext(struct device *dev, return -EINVAL; if ((count == HDMI_STOREASTEXT_BIN_SIZE) && (*buf == 0x1)) - hdmi_driver_data->store_as_hextext = true; + hdev->sysfs_data.store_as_hextext = true; else if (((count == HDMI_STOREASTEXT_TEXT_SIZE) || (count == HDMI_STOREASTEXT_TEXT_SIZE + 1)) && (*buf == '0') && (*(buf + 1) == '1')) { - hdmi_driver_data->store_as_hextext = true; + hdev->sysfs_data.store_as_hextext = true; } else { - hdmi_driver_data->store_as_hextext = false; + hdev->sysfs_data.store_as_hextext = false; } - dev_dbg(hdmidev, "store_as_hextext:%0d\n", - hdmi_driver_data->store_as_hextext); + dev_dbg(hdev->dev, "store_as_hextext:%0d\n", + hdev->sysfs_data.store_as_hextext); return count; } @@ -745,15 +803,16 @@ static ssize_t store_storeastext(struct device *dev, static ssize_t store_plugdeten(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); struct plug_detect plug_detect; int index = 0; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_PLUGDETEN_TEXT_SIZE) && (count != HDMI_PLUGDETEN_TEXT_SIZE + 1)) return -EINVAL; @@ -771,7 +830,7 @@ static ssize_t store_plugdeten(struct device *dev, plug_detect.hdmi_off_time = *(buf + index++); } - if (plugdeten(&plug_detect)) + if (plugdeten(hdev, &plug_detect)) return -EINVAL; return count; @@ -780,16 +839,17 @@ static ssize_t store_plugdeten(struct device *dev, static ssize_t store_edidread(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); struct edid_read edid_read; int index = 0; - dev_dbg(hdmidev, "%s\n", __func__); - dev_dbg(hdmidev, "count:%d\n", count); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); + dev_dbg(hdev->dev, "count:%d\n", count); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_EDIDREAD_TEXT_SIZE) && (count != HDMI_EDIDREAD_TEXT_SIZE + 1)) return -EINVAL; @@ -804,8 +864,8 @@ static ssize_t store_edidread(struct device *dev, edid_read.block_nr = *(buf + index++); } - if (edidread(&edid_read, &hdmi_driver_data->edid_data.buf_len, - hdmi_driver_data->edid_data.buf)) + if (edidread(hdev, &edid_read, &hdev->sysfs_data.edid_data.buf_len, + hdev->sysfs_data.edid_data.buf)) return -EINVAL; return count; @@ -814,42 +874,43 @@ static ssize_t store_edidread(struct device *dev, static ssize_t show_edidread(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); int len; int index = 0; int cnt; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - len = hdmi_driver_data->edid_data.buf_len; + len = hdev->sysfs_data.edid_data.buf_len; - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", len); index += 2; } else *(buf + index++) = len; - dev_dbg(hdmidev, "len:%02x\n", len); + dev_dbg(hdev->dev, "len:%02x\n", len); cnt = 0; while (cnt < len) { - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", - hdmi_driver_data->edid_data.buf[cnt]); + hdev->sysfs_data.edid_data.buf[cnt]); index += 2; } else *(buf + index++) = - hdmi_driver_data->edid_data.buf[cnt]; + hdev->sysfs_data.edid_data.buf[cnt]; - dev_dbg(hdmidev, "%02x ", - hdmi_driver_data->edid_data.buf[cnt]); + dev_dbg(hdev->dev, "%02x ", + hdev->sysfs_data.edid_data.buf[cnt]); cnt++; } - if (hdmi_driver_data->store_as_hextext) + if (hdev->sysfs_data.store_as_hextext) index++; return index; @@ -858,14 +919,15 @@ static ssize_t show_edidread(struct device *dev, struct device_attribute *attr, static ssize_t store_ceceven(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); bool enable = false; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_CECEVEN_TEXT_SIZE) && (count != HDMI_CECEVEN_TEXT_SIZE + 1)) return -EINVAL; @@ -878,7 +940,7 @@ static ssize_t store_ceceven(struct device *dev, enable = true; } - event_enable(enable, HDMI_EVENT_CEC | HDMI_EVENT_CECTXERR | + event_enable(hdev, enable, HDMI_EVENT_CEC | HDMI_EVENT_CECTXERR | HDMI_EVENT_CECTX); return count; @@ -887,20 +949,21 @@ static ssize_t store_ceceven(struct device *dev, static ssize_t show_cecread(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); struct cec_rw cec_read; int index = 0; int cnt; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (cecread(&cec_read.src, &cec_read.dest, &cec_read.length, + if (cecread(hdev, &cec_read.src, &cec_read.dest, &cec_read.length, cec_read.data)) return -EINVAL; - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", cec_read.src); index += 2; snprintf(buf + index, 3, "%02x", cec_read.dest); @@ -913,22 +976,22 @@ static ssize_t show_cecread(struct device *dev, struct device_attribute *attr, *(buf + index++) = cec_read.length; } - dev_dbg(hdmidev, "len:%02x\n", cec_read.length); + dev_dbg(hdev->dev, "len:%02x\n", cec_read.length); cnt = 0; while (cnt < cec_read.length) { - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", cec_read.data[cnt]); index += 2; } else *(buf + index++) = cec_read.data[cnt]; - dev_dbg(hdmidev, "%02x ", cec_read.data[cnt]); + dev_dbg(hdev->dev, "%02x ", cec_read.data[cnt]); cnt++; } - if (hdmi_driver_data->store_as_hextext) + if (hdev->sysfs_data.store_as_hextext) index++; return index; @@ -937,21 +1000,22 @@ static ssize_t show_cecread(struct device *dev, struct device_attribute *attr, static ssize_t store_cecsend(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); struct cec_rw cec_w; int index = 0; int cnt; int store_as_text; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); if ((*buf == 'F') || (*buf == 'f')) /* To be able to override bin format for test purpose */ store_as_text = 1; else - store_as_text = hdmi_driver_data->store_as_hextext; + store_as_text = hdev->sysfs_data.store_as_hextext; if (store_as_text) { if ((count < HDMI_CECSEND_TEXT_SIZE_MIN) || @@ -970,7 +1034,7 @@ static ssize_t store_cecsend(struct device *dev, while (cnt < cec_w.length) { cec_w.data[cnt] = htoi(buf + index); index += 2; - dev_dbg(hdmidev, "%02x ", cec_w.data[cnt]); + dev_dbg(hdev->dev, "%02x ", cec_w.data[cnt]); cnt++; } } else { @@ -986,10 +1050,7 @@ static ssize_t store_cecsend(struct device *dev, memcpy(cec_w.data, buf + index, cec_w.length); } - if (cecsend(cec_w.src, - cec_w.dest, - cec_w.length, - cec_w.data)) + if (cecsend(hdev, cec_w.src, cec_w.dest, cec_w.length, cec_w.data)) return -EINVAL; return count; @@ -998,16 +1059,17 @@ static ssize_t store_cecsend(struct device *dev, static ssize_t store_infofrsend(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); struct info_fr info_fr; int index = 0; int cnt; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count < HDMI_INFOFRSEND_TEXT_SIZE_MIN) || (count > HDMI_INFOFRSEND_TEXT_SIZE_MAX)) return -EINVAL; @@ -1027,7 +1089,7 @@ static ssize_t store_infofrsend(struct device *dev, while (cnt < info_fr.length) { info_fr.data[cnt] = htoi(buf + index); index += 2; - dev_dbg(hdmidev, "%02x ", info_fr.data[cnt]); + dev_dbg(hdev->dev, "%02x ", info_fr.data[cnt]); cnt++; } } else { @@ -1045,7 +1107,7 @@ static ssize_t store_infofrsend(struct device *dev, memcpy(info_fr.data, buf + index, info_fr.length); } - if (infofrsend(info_fr.type, info_fr.ver, info_fr.crc, + if (infofrsend(hdev, info_fr.type, info_fr.ver, info_fr.crc, info_fr.length, info_fr.data)) return -EINVAL; @@ -1055,14 +1117,15 @@ static ssize_t store_infofrsend(struct device *dev, static ssize_t store_hdcpeven(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); bool enable = false; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_HDCPEVEN_TEXT_SIZE) && (count != HDMI_HDCPEVEN_TEXT_SIZE + 1)) return -EINVAL; @@ -1075,7 +1138,7 @@ static ssize_t store_hdcpeven(struct device *dev, enable = true; } - event_enable(enable, HDMI_EVENT_HDCP); + event_enable(hdev, enable, HDMI_EVENT_HDCP); return count; } @@ -1083,28 +1146,29 @@ static ssize_t store_hdcpeven(struct device *dev, static ssize_t show_hdcpchkaesotp(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); u8 crc; u8 progged; int index = 0; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdcpchkaesotp(&crc, &progged)) + if (hdcpchkaesotp(hdev, &crc, &progged)) return -EINVAL; - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", progged); index += 2; } else { *(buf + index++) = progged; } - dev_dbg(hdmidev, "progged:%02x\n", progged); + dev_dbg(hdev->dev, "progged:%02x\n", progged); - if (hdmi_driver_data->store_as_hextext) + if (hdev->sysfs_data.store_as_hextext) index++; return index; @@ -1113,19 +1177,20 @@ static ssize_t show_hdcpchkaesotp(struct device *dev, static ssize_t store_hdcpfuseaes(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); struct hdcp_fuseaes hdcp_fuseaes; int index = 0; int cnt; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); /* Default not OK */ - hdmi_driver_data->fuse_result = HDMI_RESULT_NOT_OK; + hdev->sysfs_data.fuse_result = HDMI_RESULT_NOT_OK; - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_HDCP_FUSEAES_TEXT_SIZE) && (count != HDMI_HDCP_FUSEAES_TEXT_SIZE + 1)) return -EINVAL; @@ -1134,12 +1199,12 @@ static ssize_t store_hdcpfuseaes(struct device *dev, while (cnt < HDMI_HDCP_FUSEAES_KEYSIZE) { hdcp_fuseaes.key[cnt] = htoi(buf + index); index += 2; - dev_dbg(hdmidev, "%02x ", hdcp_fuseaes.key[cnt]); + dev_dbg(hdev->dev, "%02x ", hdcp_fuseaes.key[cnt]); cnt++; } hdcp_fuseaes.crc = htoi(&buf[index]); index += 2; - dev_dbg(hdmidev, "%02x ", hdcp_fuseaes.crc); + dev_dbg(hdev->dev, "%02x ", hdcp_fuseaes.crc); } else { if (count != HDMI_HDCP_FUSEAES_BIN_SIZE) return -EINVAL; @@ -1150,13 +1215,13 @@ static ssize_t store_hdcpfuseaes(struct device *dev, hdcp_fuseaes.crc = *(buf + index++); } - if (hdcpfuseaes(hdcp_fuseaes.key, hdcp_fuseaes.crc, + if (hdcpfuseaes(hdev, hdcp_fuseaes.key, hdcp_fuseaes.crc, &hdcp_fuseaes.result)) return -EINVAL; - dev_dbg(hdmidev, "fuseresult:%02x ", hdcp_fuseaes.result); + dev_dbg(hdev->dev, "fuseresult:%02x ", hdcp_fuseaes.result); - hdmi_driver_data->fuse_result = hdcp_fuseaes.result; + hdev->sysfs_data.fuse_result = hdcp_fuseaes.result; return count; } @@ -1164,23 +1229,23 @@ static ssize_t store_hdcpfuseaes(struct device *dev, static ssize_t show_hdcpfuseaes(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); int index = 0; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { - snprintf(buf + index, 3, "%02x", - hdmi_driver_data->fuse_result); + if (hdev->sysfs_data.store_as_hextext) { + snprintf(buf + index, 3, "%02x", hdev->sysfs_data.fuse_result); index += 2; } else - *(buf + index++) = hdmi_driver_data->fuse_result; + *(buf + index++) = hdev->sysfs_data.fuse_result; - dev_dbg(hdmidev, "status:%02x\n", hdmi_driver_data->fuse_result); + dev_dbg(hdev->dev, "status:%02x\n", hdev->sysfs_data.fuse_result); - if (hdmi_driver_data->store_as_hextext) + if (hdev->sysfs_data.store_as_hextext) index++; return index; @@ -1189,7 +1254,7 @@ static ssize_t show_hdcpfuseaes(struct device *dev, static ssize_t store_hdcploadaes(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); struct hdcp_loadaesone hdcp_loadaes; int index = 0; int block_cnt; @@ -1198,14 +1263,15 @@ static ssize_t store_hdcploadaes(struct device *dev, u8 crc; u8 progged; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); /* Default not OK */ - hdmi_driver_data->loadaes_result = HDMI_RESULT_NOT_OK; + hdev->sysfs_data.loadaes_result = HDMI_RESULT_NOT_OK; - if (hdcpchkaesotp(&crc, &progged)) + if (hdcpchkaesotp(hdev, &crc, &progged)) return -EINVAL; if (!progged) { @@ -1214,10 +1280,10 @@ static ssize_t store_hdcploadaes(struct device *dev, goto store_hdcploadaes_err; } - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_HDCP_LOADAES_TEXT_SIZE) && (count != HDMI_HDCP_LOADAES_TEXT_SIZE + 1)) { - dev_err(hdmidev, "%s", "count mismatch\n"); + dev_err(hdev->dev, "%s", "count mismatch\n"); return -EINVAL; } @@ -1228,17 +1294,18 @@ static ssize_t store_hdcploadaes(struct device *dev, while (cnt < HDMI_HDCP_AES_KEYSIZE) { hdcp_loadaes.key[cnt] = htoi(buf + index); index += 2; - dev_dbg(hdmidev, "%02x ", + dev_dbg(hdev->dev, "%02x ", hdcp_loadaes.key[cnt]); cnt++; } - if (hdcploadaes(block_cnt + HDMI_HDCP_AES_BLOCK_START, + if (hdcploadaes(hdev, + block_cnt + HDMI_HDCP_AES_BLOCK_START, HDMI_HDCP_AES_KEYSIZE, hdcp_loadaes.key, &hdcp_loadaes.result, crc32_rcvd)) { - dev_err(hdmidev, "%s %d\n", + dev_err(hdev->dev, "%s %d\n", "hdcploadaes err aes block", block_cnt + HDMI_HDCP_AES_BLOCK_START); return -EINVAL; @@ -1258,17 +1325,18 @@ static ssize_t store_hdcploadaes(struct device *dev, hdcp_loadaes.key[cnt] = htoi(&buf[index]); index += 2; - dev_dbg(hdmidev, "%02x ", hdcp_loadaes.key[cnt]); + dev_dbg(hdev->dev, "%02x ", hdcp_loadaes.key[cnt]); cnt++; } - if (hdcploadaes(HDMI_HDCP_KSV_BLOCK, + if (hdcploadaes(hdev, HDMI_HDCP_KSV_BLOCK, HDMI_HDCP_AES_KSVSIZE + HDMI_HDCP_AES_KSVZEROESSIZE, hdcp_loadaes.key, &hdcp_loadaes.result, NULL)) { - dev_err(hdmidev, "%s %d\n", "hdcploadaes err in ksv\n", + dev_err(hdev->dev, + "%s %d\n", "hdcploadaes err in ksv\n", block_cnt + HDMI_HDCP_AES_BLOCK_START); return -EINVAL; } @@ -1283,7 +1351,7 @@ static ssize_t store_hdcploadaes(struct device *dev, } if (memcmp(hdcp_loadaes.crc32, crc32_rcvd, CRC32_SIZE)) { - dev_dbg(hdmidev, "crc32exp:%02x%02x%02x%02x\n", + dev_dbg(hdev->dev, "crc32exp:%02x%02x%02x%02x\n", hdcp_loadaes.crc32[0], hdcp_loadaes.crc32[1], hdcp_loadaes.crc32[2], @@ -1293,7 +1361,7 @@ static ssize_t store_hdcploadaes(struct device *dev, } } else { if (count != HDMI_HDCP_LOADAES_BIN_SIZE) { - dev_err(hdmidev, "%s", "count mismatch\n"); + dev_err(hdev->dev, "%s", "count mismatch\n"); return -EINVAL; } @@ -1304,12 +1372,13 @@ static ssize_t store_hdcploadaes(struct device *dev, HDMI_HDCP_AES_KEYSIZE); index += HDMI_HDCP_AES_KEYSIZE; - if (hdcploadaes(block_cnt + HDMI_HDCP_AES_BLOCK_START, + if (hdcploadaes(hdev, + block_cnt + HDMI_HDCP_AES_BLOCK_START, HDMI_HDCP_AES_KEYSIZE, hdcp_loadaes.key, &hdcp_loadaes.result, crc32_rcvd)) { - dev_err(hdmidev, "%s %d\n", + dev_err(hdev->dev, "%s %d\n", "hdcploadaes err aes block", block_cnt + HDMI_HDCP_AES_BLOCK_START); return -EINVAL; @@ -1328,13 +1397,14 @@ static ssize_t store_hdcploadaes(struct device *dev, HDMI_HDCP_AES_KSVSIZE); index += HDMI_HDCP_AES_KSVSIZE; - if (hdcploadaes(HDMI_HDCP_KSV_BLOCK, + if (hdcploadaes(hdev, HDMI_HDCP_KSV_BLOCK, HDMI_HDCP_AES_KSVSIZE + HDMI_HDCP_AES_KSVZEROESSIZE, hdcp_loadaes.key, &hdcp_loadaes.result, NULL)) { - dev_err(hdmidev, "%s %d\n", "hdcploadaes err in ksv\n", + dev_err(hdev->dev, "%s %d\n", + "hdcploadaes err in ksv\n", block_cnt + HDMI_HDCP_AES_BLOCK_START); return -EINVAL; } @@ -1344,7 +1414,7 @@ static ssize_t store_hdcploadaes(struct device *dev, /* CRC32 */ if (memcmp(hdcp_loadaes.crc32, crc32_rcvd, CRC32_SIZE)) { - dev_dbg(hdmidev, "crc32exp:%02x%02x%02x%02x\n", + dev_dbg(hdev->dev, "crc32exp:%02x%02x%02x%02x\n", hdcp_loadaes.crc32[0], hdcp_loadaes.crc32[1], hdcp_loadaes.crc32[2], @@ -1354,30 +1424,31 @@ static ssize_t store_hdcploadaes(struct device *dev, } store_hdcploadaes_err: - hdmi_driver_data->loadaes_result = hdcp_loadaes.result; + hdev->sysfs_data.loadaes_result = hdcp_loadaes.result; return count; } static ssize_t show_hdcploadaes(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); int index = 0; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", - hdmi_driver_data->loadaes_result); + hdev->sysfs_data.loadaes_result); index += 2; } else - *(buf + index++) = hdmi_driver_data->loadaes_result; + *(buf + index++) = hdev->sysfs_data.loadaes_result; - dev_dbg(hdmidev, "result:%02x\n", hdmi_driver_data->loadaes_result); + dev_dbg(hdev->dev, "result:%02x\n", hdev->sysfs_data.loadaes_result); - if (hdmi_driver_data->store_as_hextext) + if (hdev->sysfs_data.store_as_hextext) index++; return index; @@ -1386,21 +1457,22 @@ static ssize_t show_hdcploadaes(struct device *dev, static ssize_t store_hdcpauthencr(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); struct hdcp_authencr hdcp_authencr; int index = 0; u8 crc; u8 progged; int result = HDMI_RESULT_NOT_OK; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - /* Default not OK */ - hdmi_driver_data->authencr.buf_len = 0; + /* Default */ + hdev->sysfs_data.authencr.buf_len = 0; - if (hdcpchkaesotp(&crc, &progged)) { + if (hdcpchkaesotp(hdev, &crc, &progged)) { result = HDMI_AES_NOT_FUSED; goto store_hdcpauthencr_end; } @@ -1411,7 +1483,7 @@ static ssize_t store_hdcpauthencr(struct device *dev, goto store_hdcpauthencr_end; } - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_HDCPAUTHENCR_TEXT_SIZE) && (count != HDMI_HDCPAUTHENCR_TEXT_SIZE + 1)) goto store_hdcpauthencr_end; @@ -1428,64 +1500,65 @@ static ssize_t store_hdcpauthencr(struct device *dev, hdcp_authencr.encr_type = *(buf + index++); } - if (hdcpauthencr(hdcp_authencr.auth_type, hdcp_authencr.encr_type, - &hdmi_driver_data->authencr.buf_len, - hdmi_driver_data->authencr.buf)) + if (hdcpauthencr(hdev, hdcp_authencr.auth_type, hdcp_authencr.encr_type, + &hdev->sysfs_data.authencr.buf_len, + hdev->sysfs_data.authencr.buf)) goto store_hdcpauthencr_end; result = HDMI_RESULT_OK; store_hdcpauthencr_end: - hdmi_driver_data->authencr.result = result; + hdev->sysfs_data.authencr.result = result; return count; } static ssize_t show_hdcpauthencr(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); int len; int index = 0; int cnt; - dev_dbg(hdmidev, "%s\n", __func__); - - hdmi_driver_data = dev_get_drvdata(dev); + if (!hdev) + return -EFAULT; + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { + /* result */ + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", - hdmi_driver_data->authencr.result); + hdev->sysfs_data.authencr.result); index += 2; } else - *(buf + index++) = hdmi_driver_data->authencr.result; + *(buf + index++) = hdev->sysfs_data.authencr.result; - dev_dbg(hdmidev, "result:%02x\n", hdmi_driver_data->authencr.result); + dev_dbg(hdev->dev, "result:%02x\n", hdev->sysfs_data.authencr.result); /* resp_size */ - len = hdmi_driver_data->authencr.buf_len; + len = hdev->sysfs_data.authencr.buf_len; if (len > AUTH_BUF_LEN) len = AUTH_BUF_LEN; - dev_dbg(hdmidev, "resp_size:%d\n", len); + dev_dbg(hdev->dev, "resp_size:%d\n", len); /* resp */ cnt = 0; while (cnt < len) { - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", - hdmi_driver_data->authencr.buf[cnt]); + hdev->sysfs_data.authencr.buf[cnt]); index += 2; - dev_dbg(hdmidev, "%02x ", - hdmi_driver_data->authencr.buf[cnt]); + dev_dbg(hdev->dev, "%02x ", + hdev->sysfs_data.authencr.buf[cnt]); } else - *(buf + index++) = hdmi_driver_data->authencr.buf[cnt]; + *(buf + index++) = hdev->sysfs_data.authencr.buf[cnt]; cnt++; } - if (hdmi_driver_data->store_as_hextext) + if (hdev->sysfs_data.store_as_hextext) index++; return index; @@ -1494,26 +1567,27 @@ static ssize_t show_hdcpauthencr(struct device *dev, static ssize_t show_hdcpstateget(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); u8 hdcp_state; int index = 0; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); if (av8100_reg_gen_status_r(NULL, NULL, NULL, NULL, NULL, &hdcp_state)) return -EINVAL; - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", hdcp_state); index += 2; } else *(buf + index++) = hdcp_state; - dev_dbg(hdmidev, "status:%02x\n", hdcp_state); + dev_dbg(hdev->dev, "status:%02x\n", hdcp_state); - if (hdmi_driver_data->store_as_hextext) + if (hdev->sysfs_data.store_as_hextext) index++; return index; @@ -1522,27 +1596,28 @@ static ssize_t show_hdcpstateget(struct device *dev, static ssize_t show_evread(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); int index = 0; u8 ev; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - ev = events_read(); + ev = events_read(hdev); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", ev); index += 2; } else *(buf + index++) = ev; - if (hdmi_driver_data->store_as_hextext) + if (hdev->sysfs_data.store_as_hextext) index++; /* Events are read: clear events */ - events_clear(EVENTS_MASK); + events_clear(hdev, EVENTS_MASK); return index; } @@ -1550,15 +1625,16 @@ static ssize_t show_evread(struct device *dev, struct device_attribute *attr, static ssize_t store_evclr(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); u8 ev; int index = 0; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_EVCLR_TEXT_SIZE) && (count != HDMI_EVCLR_TEXT_SIZE + 1)) return -EINVAL; @@ -1572,7 +1648,7 @@ static ssize_t store_evclr(struct device *dev, ev = *(buf + index++); } - events_clear(ev); + events_clear(hdev, ev); return count; } @@ -1580,15 +1656,16 @@ static ssize_t store_evclr(struct device *dev, static ssize_t store_audiocfg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); struct audio_cfg audio_cfg; int index = 0; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_AUDIOCFG_TEXT_SIZE) && (count != HDMI_AUDIOCFG_TEXT_SIZE + 1)) return -EINVAL; @@ -1620,7 +1697,7 @@ static ssize_t store_audiocfg(struct device *dev, audio_cfg.mute = *(buf + index++); } - audiocfg(&audio_cfg); + audiocfg(hdev, &audio_cfg); return count; } @@ -1628,25 +1705,26 @@ static ssize_t store_audiocfg(struct device *dev, static ssize_t show_plugstatus(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); int index = 0; struct av8100_status av8100_status; u8 plstat; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); av8100_status = av8100_status_get(); plstat = av8100_status.av8100_plugin_status == AV8100_HDMI_PLUGIN; - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", plstat); index += 2; } else *(buf + index++) = plstat; - if (hdmi_driver_data->store_as_hextext) + if (hdev->sysfs_data.store_as_hextext) index++; return index; @@ -1655,14 +1733,15 @@ static ssize_t show_plugstatus(struct device *dev, static ssize_t store_poweronoff(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); bool enable = false; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { if ((count != HDMI_POWERONOFF_TEXT_SIZE) && (count != HDMI_POWERONOFF_TEXT_SIZE + 1)) return -EINVAL; @@ -1677,12 +1756,12 @@ static ssize_t store_poweronoff(struct device *dev, if (enable == 0) { if (av8100_powerdown() != 0) { - dev_err(hdmidev, "av8100_powerdown FAIL\n"); + dev_err(hdev->dev, "av8100_powerdown FAIL\n"); return -EINVAL; } } else { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup FAIL\n"); + dev_err(hdev->dev, "av8100_powerup FAIL\n"); return -EINVAL; } } @@ -1693,14 +1772,15 @@ static ssize_t store_poweronoff(struct device *dev, static ssize_t show_poweronoff(struct device *dev, struct device_attribute *attr, char *buf) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = dev_to_hdev(dev); int index = 0; struct av8100_status status; u8 power_state; - dev_dbg(hdmidev, "%s\n", __func__); + if (!hdev) + return -EFAULT; - hdmi_driver_data = dev_get_drvdata(dev); + dev_dbg(hdev->dev, "%s\n", __func__); status = av8100_status_get(); if (status.av8100_state < AV8100_OPMODE_SCAN) @@ -1708,7 +1788,7 @@ static ssize_t show_poweronoff(struct device *dev, else power_state = 1; - if (hdmi_driver_data->store_as_hextext) { + if (hdev->sysfs_data.store_as_hextext) { snprintf(buf + index, 3, "%02x", power_state); index += 3; } else { @@ -1721,28 +1801,25 @@ static ssize_t show_poweronoff(struct device *dev, static ssize_t store_evwakeup(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - dev_dbg(hdmidev, "%s\n", __func__); + struct hdmi_device *hdev = dev_to_hdev(dev); + + if (!hdev) + return -EFAULT; + + dev_dbg(hdev->dev, "%s\n", __func__); - event_wakeup(); + event_wakeup(hdev); return count; } static int hdmi_open(struct inode *inode, struct file *filp) { - if (device_open) - return -EBUSY; - - device_open++; - return 0; } static int hdmi_release(struct inode *inode, struct file *filp) { - if (device_open) - device_open--; - return 0; } @@ -1754,6 +1831,7 @@ static long hdmi_ioctl(struct file *file, struct hdmi_register reg; struct av8100_status status; u8 aes_status; + struct hdmi_device *hdev = devnr_to_hdev(HDMI_DEVNR_DEFAULT); switch (cmd) { case IOC_PLUG_DETECT_ENABLE: @@ -1764,7 +1842,7 @@ static long hdmi_ioctl(struct file *file, sizeof(struct plug_detect))) return -EINVAL; - if (plugdeten(&plug_detect)) + if (plugdeten(hdev, &plug_detect)) return -EINVAL; } break; @@ -1777,7 +1855,7 @@ static long hdmi_ioctl(struct file *file, sizeof(struct edid_read))) return -EINVAL; - if (edidread(&edid_read, &edid_read.data_length, + if (edidread(hdev, &edid_read, &edid_read.data_length, edid_read.data)) return -EINVAL; @@ -1792,7 +1870,8 @@ static long hdmi_ioctl(struct file *file, if (copy_from_user(&value, (void *)arg, sizeof(u8))) return -EINVAL; - event_enable(value != 0, HDMI_EVENT_CEC | HDMI_EVENT_CECTXERR | + event_enable(hdev, value != 0, + HDMI_EVENT_CEC | HDMI_EVENT_CECTXERR | HDMI_EVENT_CECTX); break; @@ -1800,8 +1879,8 @@ static long hdmi_ioctl(struct file *file, { struct cec_rw cec_read; - if (cecread(&cec_read.src, &cec_read.dest, &cec_read.length, - cec_read.data)) + if (cecread(hdev, &cec_read.src, &cec_read.dest, + &cec_read.length, cec_read.data)) return -EINVAL; if (copy_to_user((void *)arg, (void *)&cec_read, @@ -1819,9 +1898,7 @@ static long hdmi_ioctl(struct file *file, sizeof(struct cec_rw))) return -EINVAL; - if (cecsend(cec_send.src, - cec_send.dest, - cec_send.length, + if (cecsend(hdev, cec_send.src, cec_send.dest, cec_send.length, cec_send.data)) return -EINVAL; } @@ -1835,7 +1912,7 @@ static long hdmi_ioctl(struct file *file, sizeof(struct info_fr))) return -EINVAL; - if (infofrsend(info_fr.type, info_fr.ver, info_fr.crc, + if (infofrsend(hdev, info_fr.type, info_fr.ver, info_fr.crc, info_fr.length, info_fr.data)) return -EINVAL; } @@ -1845,11 +1922,11 @@ static long hdmi_ioctl(struct file *file, if (copy_from_user(&value, (void *)arg, sizeof(u8))) return -EINVAL; - event_enable(value != 0, HDMI_EVENT_HDCP); + event_enable(hdev, value != 0, HDMI_EVENT_HDCP); break; case IOC_HDCP_CHKAESOTP: - if (hdcpchkaesotp(&value, &aes_status)) + if (hdcpchkaesotp(hdev, &value, &aes_status)) return -EINVAL; if (copy_to_user((void *)arg, (void *)&aes_status, @@ -1866,7 +1943,7 @@ static long hdmi_ioctl(struct file *file, sizeof(struct hdcp_fuseaes))) return -EINVAL; - if (hdcpfuseaes(hdcp_fuseaes.key, hdcp_fuseaes.crc, + if (hdcpfuseaes(hdev, hdcp_fuseaes.key, hdcp_fuseaes.crc, &hdcp_fuseaes.result)) return -EINVAL; @@ -1887,7 +1964,7 @@ static long hdmi_ioctl(struct file *file, sizeof(struct hdcp_loadaesall))) return -EINVAL; - if (hdcpchkaesotp(&value, &aes_status)) + if (hdcpchkaesotp(hdev, &value, &aes_status)) return -EINVAL; if (!aes_status) { @@ -1903,7 +1980,8 @@ static long hdmi_ioctl(struct file *file, block_cnt * HDMI_HDCP_AES_KEYSIZE, HDMI_HDCP_AES_KEYSIZE); - if (hdcploadaes(block_cnt + HDMI_HDCP_AES_BLOCK_START, + if (hdcploadaes(hdev, + block_cnt + HDMI_HDCP_AES_BLOCK_START, HDMI_HDCP_AES_KEYSIZE, hdcp_loadaesone.key, &hdcp_loadaesone.result, @@ -1921,7 +1999,7 @@ static long hdmi_ioctl(struct file *file, memcpy(hdcp_loadaesone.key + HDMI_HDCP_AES_KSVZEROESSIZE, hdcp_loadaesall.ksv, HDMI_HDCP_AES_KSVSIZE); - if (hdcploadaes(HDMI_HDCP_KSV_BLOCK, + if (hdcploadaes(hdev, HDMI_HDCP_KSV_BLOCK, HDMI_HDCP_AES_KSVSIZE + HDMI_HDCP_AES_KSVZEROESSIZE, hdcp_loadaesone.key, @@ -1935,7 +2013,7 @@ static long hdmi_ioctl(struct file *file, /* CRC32 */ if (memcmp(hdcp_loadaesall.crc32, hdcp_loadaesone.crc32, CRC32_SIZE)) { - dev_dbg(hdmidev, "crc32exp:%02x%02x%02x%02x\n", + dev_dbg(hdev->dev, "crc32exp:%02x%02x%02x%02x\n", hdcp_loadaesall.crc32[0], hdcp_loadaesall.crc32[1], hdcp_loadaesall.crc32[2], @@ -1968,7 +2046,7 @@ ioc_hdcploadaes_err: /* Default not OK */ hdcp_authencr.resp_size = 0; - if (hdcpchkaesotp(&value, &aes_status)) { + if (hdcpchkaesotp(hdev, &value, &aes_status)) { result = HDMI_AES_NOT_FUSED; goto hdcp_authencr_end; } @@ -1979,7 +2057,7 @@ ioc_hdcploadaes_err: goto hdcp_authencr_end; } - if (hdcpauthencr(hdcp_authencr.auth_type, + if (hdcpauthencr(hdev, hdcp_authencr.auth_type, hdcp_authencr.encr_type, &value, buf)) { @@ -2014,7 +2092,7 @@ hdcp_authencr_end: break; case IOC_EVENTS_READ: - value = events_read(); + value = events_read(hdev); if (copy_to_user((void *)arg, (void *)&value, sizeof(u8))) { @@ -2022,14 +2100,14 @@ hdcp_authencr_end: } /* Events are read: clear events */ - events_clear(EVENTS_MASK); + events_clear(hdev, EVENTS_MASK); break; case IOC_EVENTS_CLEAR: if (copy_from_user(&value, (void *)arg, sizeof(u8))) return -EINVAL; - events_clear(value); + events_clear(hdev, value); break; case IOC_AUDIO_CFG: @@ -2040,7 +2118,7 @@ hdcp_authencr_end: sizeof(struct audio_cfg))) return -EINVAL; - audiocfg(&audio_cfg); + audiocfg(hdev, &audio_cfg); } break; @@ -2061,12 +2139,12 @@ hdcp_authencr_end: if (value == 0) { if (av8100_powerdown() != 0) { - dev_err(hdmidev, "av8100_powerdown FAIL\n"); + dev_err(hdev->dev, "av8100_powerdown FAIL\n"); return -EINVAL; } } else { if (av8100_powerup() != 0) { - dev_err(hdmidev, "av8100_powerup FAIL\n"); + dev_err(hdev->dev, "av8100_powerup FAIL\n"); return -EINVAL; } } @@ -2074,7 +2152,7 @@ hdcp_authencr_end: case IOC_EVENT_WAKEUP: /* Trigger event */ - event_wakeup(); + event_wakeup(hdev); break; case IOC_POWERSTATE: @@ -2091,14 +2169,14 @@ hdcp_authencr_end: case IOC_HDMI_ENABLE_INTERRUPTS: av8100_disable_interrupt(); if (av8100_enable_interrupt() != 0) { - dev_err(hdmidev, "av8100_conf_get FAIL\n"); + dev_err(hdev->dev, "av8100_ei FAIL\n"); return -EINVAL; } break; case IOC_HDMI_DOWNLOAD_FW: if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100 dl fw FAIL\n"); + dev_err(hdev->dev, "av8100 dl fw FAIL\n"); return -EINVAL; } break; @@ -2112,7 +2190,7 @@ hdcp_authencr_end: return -EFAULT; if (av8100_conf_get(AV8100_COMMAND_HDMI, &config) != 0) { - dev_err(hdmidev, "av8100_conf_get FAIL\n"); + dev_err(hdev->dev, "av8100_conf_get FAIL\n"); return -EINVAL; } if (value == 0) @@ -2121,12 +2199,12 @@ hdcp_authencr_end: config.hdmi_format.hdmi_mode = AV8100_HDMI_ON; if (av8100_conf_prep(AV8100_COMMAND_HDMI, &config) != 0) { - dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + dev_err(hdev->dev, "av8100_conf_prep FAIL\n"); return -EINVAL; } if (av8100_conf_w(AV8100_COMMAND_HDMI, NULL, NULL, I2C_INTERFACE) != 0) { - dev_err(hdmidev, "av8100_conf_w FAIL\n"); + dev_err(hdev->dev, "av8100_conf_w FAIL\n"); return -EINVAL; } } @@ -2139,7 +2217,7 @@ hdcp_authencr_end: } if (av8100_reg_w(reg.offset, reg.value) != 0) { - dev_err(hdmidev, "hdmi_register_write FAIL\n"); + dev_err(hdev->dev, "hdmi_register_write FAIL\n"); return -EINVAL; } break; @@ -2151,7 +2229,7 @@ hdcp_authencr_end: } if (av8100_reg_r(reg.offset, ®.value) != 0) { - dev_err(hdmidev, "hdmi_register_write FAIL\n"); + dev_err(hdev->dev, "hdmi_register_write FAIL\n"); return -EINVAL; } @@ -2173,9 +2251,10 @@ hdcp_authencr_end: case IOC_HDMI_CONFIGURATION_WRITE: { struct hdmi_command_register command_reg; + if (copy_from_user(&command_reg, (void *)arg, sizeof(struct hdmi_command_register)) != 0) { - dev_err(hdmidev, "IOC_HDMI_CONFIGURATION_WRITE " + dev_err(hdev->dev, "IOC_HDMI_CONFIGURATION_WRITE " "fail 1\n"); command_reg.return_status = EINVAL; } else { @@ -2185,7 +2264,8 @@ hdcp_authencr_end: command_reg.buf, &(command_reg.buf_len), command_reg.buf) != 0) { - dev_err(hdmidev, "IOC_HDMI_CONFIGURATION_WRITE " + dev_err(hdev->dev, + "IOC_HDMI_CONFIGURATION_WRITE " "fail 2\n"); command_reg.return_status = EINVAL; } @@ -2209,14 +2289,19 @@ static unsigned int hdmi_poll(struct file *filp, poll_table *wait) { unsigned int mask = 0; + struct hdmi_device *hdev; + + hdev = devnr_to_hdev(HDMI_DEVNR_DEFAULT); + if (!hdev) + return 0; - dev_dbg(hdmidev, "%s\n", __func__); + dev_dbg(hdev->dev, "%s\n", __func__); - poll_wait(filp, &hdmi_event_wq , wait); + poll_wait(filp, &hdev->event_wq , wait); LOCK_HDMI_EVENTS; - if (events_received == true) { - events_received = false; + if (hdev->events_received == true) { + hdev->events_received = false; mask = POLLIN | POLLRDNORM; } UNLOCK_HDMI_EVENTS; @@ -2232,180 +2317,164 @@ static const struct file_operations hdmi_fops = { .poll = hdmi_poll }; -static struct miscdevice hdmi_miscdev = { - MISC_DYNAMIC_MINOR, - "hdmi", - &hdmi_fops -}; - /* Event callback function called by hw driver */ void hdmi_event(enum av8100_hdmi_event ev) { int events_old; int events_new; - struct kobject *kobj = &hdmidev->kobj; + struct hdmi_device *hdev; + struct kobject *kobj; + + hdev = devnr_to_hdev(HDMI_DEVNR_DEFAULT); + if (!hdev) + return; + + dev_dbg(hdev->dev, "hdmi_event %02x\n", ev); - dev_dbg(hdmidev, "hdmi_event %02x\n", ev); + kobj = &(hdev->dev->kobj); LOCK_HDMI_EVENTS; - events_old = events; + events_old = hdev->events; /* Set event */ switch (ev) { case AV8100_HDMI_EVENT_HDMI_PLUGIN: - events &= ~HDMI_EVENT_HDMI_PLUGOUT; - events |= HDMI_EVENT_HDMI_PLUGIN; + hdev->events &= ~HDMI_EVENT_HDMI_PLUGOUT; + hdev->events |= HDMI_EVENT_HDMI_PLUGIN; break; case AV8100_HDMI_EVENT_HDMI_PLUGOUT: - events &= ~HDMI_EVENT_HDMI_PLUGIN; - events |= HDMI_EVENT_HDMI_PLUGOUT; - cec_tx_status(CEC_TX_SET_FREE); + hdev->events &= ~HDMI_EVENT_HDMI_PLUGIN; + hdev->events |= HDMI_EVENT_HDMI_PLUGOUT; + cec_tx_status(hdev, CEC_TX_SET_FREE); break; case AV8100_HDMI_EVENT_CEC: - events |= HDMI_EVENT_CEC; + hdev->events |= HDMI_EVENT_CEC; break; case AV8100_HDMI_EVENT_HDCP: - events |= HDMI_EVENT_HDCP; + hdev->events |= HDMI_EVENT_HDCP; break; case AV8100_HDMI_EVENT_CECTXERR: - events |= HDMI_EVENT_CECTXERR; - cec_tx_status(CEC_TX_SET_FREE); + hdev->events |= HDMI_EVENT_CECTXERR; + cec_tx_status(hdev, CEC_TX_SET_FREE); break; case AV8100_HDMI_EVENT_CECTX: - events |= HDMI_EVENT_CECTX; - cec_tx_status(CEC_TX_SET_FREE); + hdev->events |= HDMI_EVENT_CECTX; + cec_tx_status(hdev, CEC_TX_SET_FREE); break; default: break; } - events_new = events_mask & events; + events_new = hdev->events_mask & hdev->events; UNLOCK_HDMI_EVENTS; - dev_dbg(hdmidev, "hdmi events:%02x, events_old:%02x mask:%02x\n", - events_new, events_old, events_mask); + dev_dbg(hdev->dev, "hdmi events:%02x, events_old:%02x mask:%02x\n", + events_new, events_old, hdev->events_mask); if (events_new != events_old) { /* Wake up application waiting for event via call to poll() */ sysfs_notify(kobj, NULL, SYSFS_EVENT_FILENAME); LOCK_HDMI_EVENTS; - events_received = true; + hdev->events_received = true; UNLOCK_HDMI_EVENTS; - wake_up_interruptible(&hdmi_event_wq); + wake_up_interruptible(&hdev->event_wq); } } EXPORT_SYMBOL(hdmi_event); -int __init hdmi_init(void) +int hdmi_device_register(struct hdmi_device *hdev) { - int ret; - struct hdmi_driver_data *hdmi_driver_data; + hdev->miscdev.minor = MISC_DYNAMIC_MINOR; + hdev->miscdev.name = "hdmi"; + hdev->miscdev.fops = &hdmi_fops; + + if (misc_register(&hdev->miscdev)) { + pr_err("hdmi misc_register failed\n"); + return -EFAULT; + } - ret = misc_register(&hdmi_miscdev); - if (ret) - goto hdmi_init_out; + hdev->dev = hdev->miscdev.this_device; - hdmidev = hdmi_miscdev.this_device; + return 0; +} - hdmi_driver_data = - kzalloc(sizeof(struct hdmi_driver_data), GFP_KERNEL); +int __init hdmi_init(void) +{ + struct hdmi_device *hdev; + int i; + int ret; - if (!hdmi_driver_data) + /* Allocate device data */ + hdev = kzalloc(sizeof(struct hdmi_device), GFP_KERNEL); + if (!hdev) { + pr_err("%s: Alloc failure\n", __func__); return -ENOMEM; + } + + /* Add to list */ + list_add_tail(&hdev->list, &hdmi_device_list); + + if (hdmi_device_register(hdev)) { + pr_err("%s: Alloc failure\n", __func__); + return -EFAULT; + } - dev_set_drvdata(hdmidev, hdmi_driver_data); + hdev->devnr = HDMI_DEVNR_DEFAULT; /* Default sysfs file format is hextext */ - hdmi_driver_data->store_as_hextext = true; - - init_waitqueue_head(&hdmi_event_wq); - - if (device_create_file(hdmidev, &dev_attr_storeastext)) - dev_info(hdmidev, "Unable to create storeastext attribute\n"); - if (device_create_file(hdmidev, &dev_attr_plugdeten)) - dev_info(hdmidev, "Unable to create plugdeten attribute\n"); - if (device_create_file(hdmidev, &dev_attr_edidread)) - dev_info(hdmidev, "Unable to create edidread attribute\n"); - if (device_create_file(hdmidev, &dev_attr_ceceven)) - dev_info(hdmidev, "Unable to create ceceven attribute\n"); - if (device_create_file(hdmidev, &dev_attr_cecread)) - dev_info(hdmidev, "Unable to create cecread attribute\n"); - if (device_create_file(hdmidev, &dev_attr_cecsend)) - dev_info(hdmidev, "Unable to create cecsend attribute\n"); - if (device_create_file(hdmidev, &dev_attr_infofrsend)) - dev_info(hdmidev, "Unable to create infofrsend attribute\n"); - if (device_create_file(hdmidev, &dev_attr_hdcpeven)) - dev_info(hdmidev, "Unable to create hdcpeven attribute\n"); - if (device_create_file(hdmidev, &dev_attr_hdcpchkaesotp)) - dev_info(hdmidev, "Unable to create hdcpchkaesotp attribute\n"); - if (device_create_file(hdmidev, &dev_attr_hdcpfuseaes)) - dev_info(hdmidev, "Unable to create hdcpfuseaes attribute\n"); - if (device_create_file(hdmidev, &dev_attr_hdcploadaes)) - dev_info(hdmidev, "Unable to create hdcploadaes attribute\n"); - if (device_create_file(hdmidev, &dev_attr_hdcpauthencr)) - dev_info(hdmidev, "Unable to create hdcpauthreq attribute\n"); - if (device_create_file(hdmidev, &dev_attr_hdcpstateget)) - dev_info(hdmidev, "Unable to create hdcpstateget attribute\n"); - if (device_create_file(hdmidev, &dev_attr_evread)) - dev_info(hdmidev, "Unable to create evread attribute\n"); - if (device_create_file(hdmidev, &dev_attr_evclr)) - dev_info(hdmidev, "Unable to create evclr attribute\n"); - if (device_create_file(hdmidev, &dev_attr_audiocfg)) - dev_info(hdmidev, "Unable to create audiocfg attribute\n"); - if (device_create_file(hdmidev, &dev_attr_plugstatus)) - dev_info(hdmidev, "Unable to create plugstatus attribute\n"); - if (device_create_file(hdmidev, &dev_attr_poweronoff)) - dev_info(hdmidev, "Unable to create poweronoff attribute\n"); - if (device_create_file(hdmidev, &dev_attr_evwakeup)) - dev_info(hdmidev, "Unable to create evwakeup attribute\n"); + hdev->sysfs_data.store_as_hextext = true; + + init_waitqueue_head(&hdev->event_wq); + + /* Create sysfs attrs */ + for (i = 0; attr_name(hdmi_sysfs_attrs[i]); i++) { + ret = device_create_file(hdev->dev, &hdmi_sysfs_attrs[i]); + if (ret) + dev_err(hdev->dev, + "Unable to create sysfs attr %s (%d)\n", + hdmi_sysfs_attrs[i].attr.name, ret); + } /* Register event callback */ av8100_hdmi_event_cb_set(hdmi_event); -hdmi_init_out: - return ret; + return 0; } late_initcall(hdmi_init); void hdmi_exit(void) { - struct hdmi_driver_data *hdmi_driver_data; + struct hdmi_device *hdev = NULL; + int i; + + if (list_empty(&hdmi_device_list)) + return; + else + hdev = list_entry(hdmi_device_list.next, + struct hdmi_device, list); /* Deregister event callback */ av8100_hdmi_event_cb_set(NULL); - device_remove_file(hdmidev, &dev_attr_storeastext); - device_remove_file(hdmidev, &dev_attr_plugdeten); - device_remove_file(hdmidev, &dev_attr_edidread); - device_remove_file(hdmidev, &dev_attr_ceceven); - device_remove_file(hdmidev, &dev_attr_cecread); - device_remove_file(hdmidev, &dev_attr_cecsend); - device_remove_file(hdmidev, &dev_attr_infofrsend); - device_remove_file(hdmidev, &dev_attr_hdcpeven); - device_remove_file(hdmidev, &dev_attr_hdcpchkaesotp); - device_remove_file(hdmidev, &dev_attr_hdcpfuseaes); - device_remove_file(hdmidev, &dev_attr_hdcploadaes); - device_remove_file(hdmidev, &dev_attr_hdcpauthencr); - device_remove_file(hdmidev, &dev_attr_hdcpstateget); - device_remove_file(hdmidev, &dev_attr_evread); - device_remove_file(hdmidev, &dev_attr_evclr); - device_remove_file(hdmidev, &dev_attr_audiocfg); - device_remove_file(hdmidev, &dev_attr_plugstatus); - device_remove_file(hdmidev, &dev_attr_poweronoff); - device_remove_file(hdmidev, &dev_attr_evwakeup); - - hdmi_driver_data = dev_get_drvdata(hdmidev); - kfree(hdmi_driver_data); - - misc_deregister(&hdmi_miscdev); + /* Remove sysfs attrs */ + for (i = 0; attr_name(hdmi_sysfs_attrs[i]); i++) + device_remove_file(hdev->dev, &hdmi_sysfs_attrs[i]); + + misc_deregister(&hdev->miscdev); + + /* Remove from list */ + list_del(&hdev->list); + + /* Free device data */ + kfree(hdev); } diff --git a/drivers/video/av8100/hdmi_loc.h b/drivers/video/av8100/hdmi_loc.h index 063c1066334..20314910db9 100644 --- a/drivers/video/av8100/hdmi_loc.h +++ b/drivers/video/av8100/hdmi_loc.h @@ -39,7 +39,7 @@ struct hdcp_loadaesone { u8 crc32[CRC32_SIZE]; }; -struct hdmi_driver_data { +struct hdmi_sysfs_data { bool store_as_hextext; struct plug_detect plug_detect; bool enable_cec_event; diff --git a/include/video/av8100.h b/include/video/av8100.h index dcc9d51992f..b5922c8b2e5 100644 --- a/include/video/av8100.h +++ b/include/video/av8100.h @@ -28,16 +28,6 @@ struct av8100_platform_data { unsigned char mclk_freq; }; -enum av8100_error { - AV8100_OK = 0x0, - AV8100_INVALID_COMMAND = 0x1, - AV8100_INVALID_INTERFACE = 0x2, - AV8100_INVALID_IOCTL = 0x3, - AV8100_COMMAND_FAIL = 0x4, - AV8100_FWDOWNLOAD_FAIL = 0x5, - AV8100_FAIL = 0xFF, -}; - enum av8100_command_type { AV8100_COMMAND_VIDEO_INPUT_FORMAT = 0x1, AV8100_COMMAND_AUDIO_INPUT_FORMAT, |