diff --git a/Documentation/devicetree/bindings/arm/msm/adv7481.txt b/Documentation/devicetree/bindings/arm/msm/adv7481.txt new file mode 100644 index 000000000000..ea5fc3025fe2 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/adv7481.txt @@ -0,0 +1,20 @@ +ADV7481 chip driver (VIDEO_ADV7481) + +VIDEO_ADV7481 is a kernel platform driver that is used for video decoder +and dual mode HDMI/MHL receiver. + +The devicetree representation of the VIDEO_ADV7481 block should be: + +Required properties + +- compatible: "qcom,adv7481" +- qcom,slave-addr: The i2c slave address of adv7481 driver. +- qcom,cci-master: The i2c master id to be used for adv7481 driver. + +Example: + + qcom,adv7481@0 { + compatible = "qcom,adv7481"; + qcom,cci-master = <0>; + qcom,slave-addr = <0x70>; + }; diff --git a/drivers/media/i2c/adv7481.c b/drivers/media/i2c/adv7481.c index 359a860fdabb..27b8a194ce7b 100644 --- a/drivers/media/i2c/adv7481.c +++ b/drivers/media/i2c/adv7481.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -27,17 +27,27 @@ #include #include #include + +#include +#include +#include + #include #include #include "adv7481_reg.h" +#include "msm_cci.h" +#include "msm_camera_i2c.h" +#include "msm_camera_io_util.h" +#include "msm_camera_dt_util.h" + #define DRIVER_NAME "adv7481" -#define I2C_RW_DELAY 100 -#define I2C_SW_RST_DELAY 10000 -#define GPIO_HW_DELAY_LOW 100000 -#define GPIO_HW_DELAY_HI 10000 +#define I2C_RW_DELAY 1 +#define I2C_SW_RST_DELAY 5000 +#define GPIO_HW_RST_DELAY_HI 10000 +#define GPIO_HW_RST_DELAY_LOW 10000 #define SDP_MIN_SLEEP 5000 #define SDP_MAX_SLEEP 6000 #define SDP_NUM_TRIES 30 @@ -45,11 +55,44 @@ #define LOCK_MAX_SLEEP 6000 #define LOCK_NUM_TRIES 20 +#define MAX_DEFAULT_WIDTH 1280 +#define MAX_DEFAULT_HEIGHT 720 +#define MAX_DEFAULT_FRAME_RATE 60 +#define MAX_DEFAULT_PIX_CLK_HZ 74240000 + #define ONE_MHZ_TO_HZ 1000000 +enum adv7481_gpio_t { + + CCI_I2C_SDA = 0, + CCI_I2C_SCL, + + ADV7481_GPIO_RST, + + ADV7481_GPIO_INT1, + ADV7481_GPIO_INT2, + ADV7481_GPIO_INT3, + + ADV7481_GPIO_MAX, +}; + struct adv7481_state { /* Platform Data */ struct adv7481_platform_data pdata; + struct device *dev; + + /* VREG */ + struct camera_vreg_t *cci_vreg; + struct regulator *cci_reg_ptr[MAX_REGULATOR]; + int32_t regulator_count; + + /* I2C */ + struct msm_camera_i2c_client i2c_client; + u32 cci_master; + u32 i2c_slave_addr; + u32 i2c_csi_slave_addr; + u32 i2c_vpp_slave_addr; + u32 register_page; /* V4L2 Data */ struct v4l2_subdev sd; @@ -63,19 +106,24 @@ struct adv7481_state { struct workqueue_struct *work_queues; struct mutex mutex; - struct i2c_client *client; - struct i2c_client *i2c_csi_txa; - struct i2c_client *i2c_csi_txb; - struct i2c_client *i2c_hdmi; - struct i2c_client *i2c_edid; - struct i2c_client *i2c_cp; - struct i2c_client *i2c_sdp; - struct i2c_client *i2c_rep; + uint8_t i2c_io_addr; + uint8_t i2c_csi_txa_addr; + uint8_t i2c_csi_txb_addr; + uint8_t i2c_hdmi_addr; + uint8_t i2c_edid_addr; + uint8_t i2c_cp_addr; + uint8_t i2c_sdp_addr; + uint8_t i2c_rep_addr; + uint8_t i2c_cbus_addr; /* device status and Flags */ int irq; int device_num; int powerup; + int cec_detected; + + /* GPIOs */ + struct gpio gpio_array[ADV7481_GPIO_MAX]; /* routing configuration data */ int csia_src; @@ -196,6 +244,9 @@ const uint8_t adv7481_default_edid_data[] = { #define ADV7481_EDID_SIZE ARRAY_SIZE(adv7481_default_edid_data) +static u32 adv7481_inp_to_ba(u32 adv_input); +static bool adv7481_is_timing_locked(struct adv7481_state *state); + static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) { return &(container_of(ctrl->handler, @@ -208,50 +259,102 @@ static inline struct adv7481_state *to_state(struct v4l2_subdev *sd) } /* I2C Rd/Rw Functions */ -static int adv7481_wr_byte(struct i2c_client *i2c_client, unsigned int reg, - unsigned int value) +static int32_t adv7481_cci_i2c_write(struct msm_camera_i2c_client *i2c_client, + uint8_t reg, uint16_t *data, + enum msm_camera_i2c_data_type data_type) { - int ret; + return i2c_client->i2c_func_tbl->i2c_write(i2c_client, reg, + *data, data_type); +} - ret = i2c_smbus_write_byte_data(i2c_client, reg & 0xFF, value); - usleep_range(I2C_RW_DELAY, 2*I2C_RW_DELAY); +static int32_t adv7481_cci_i2c_read(struct msm_camera_i2c_client *i2c_client, + uint8_t reg, uint16_t *data, + enum msm_camera_i2c_data_type data_type) +{ + return i2c_client->i2c_func_tbl->i2c_read(i2c_client, reg, + data, data_type); +} + +static int32_t adv7481_wr_byte(struct msm_camera_i2c_client *c_i2c_client, + uint8_t sid, uint8_t reg, uint8_t data) +{ + uint16_t write_data = data; + int ret = 0; + + c_i2c_client->cci_client->sid = sid; + + ret = adv7481_cci_i2c_write(c_i2c_client, reg, &write_data, + MSM_CAMERA_I2C_BYTE_DATA); + if (ret < 0) + pr_err("Error %d writing cci i2c\n", ret); return ret; } -static int adv7481_rd_byte(struct i2c_client *i2c_client, unsigned int reg) +static uint8_t adv7481_rd_byte(struct msm_camera_i2c_client *c_i2c_client, + uint8_t sid, uint8_t reg) { + uint16_t data = 0; + int ret = 0; + + c_i2c_client->cci_client->sid = sid; + ret = adv7481_cci_i2c_read(c_i2c_client, reg, &data, + MSM_CAMERA_I2C_BYTE_DATA); + if (ret < 0) { + pr_err("Error %d reading cci i2c\n", ret); + return ret; + } + + return (uint8_t)(data & 0xFF); +} + +static uint16_t adv7481_rd_word(struct msm_camera_i2c_client *c_i2c_client, + uint8_t sid, uint8_t reg) +{ + uint16_t data = 0; int ret; - ret = i2c_smbus_read_byte_data(i2c_client, reg & 0xFF); - usleep_range(I2C_RW_DELAY, 2*I2C_RW_DELAY); + c_i2c_client->cci_client->sid = sid; + ret = adv7481_cci_i2c_read(c_i2c_client, reg, &data, + MSM_CAMERA_I2C_WORD_DATA); + if (ret < 0) { + pr_err("Error %d reading cci i2c\n", ret); + return ret; + } - return ret; + return data; } static int adv7481_set_irq(struct adv7481_state *state) { int ret = 0; - ret = adv7481_wr_byte(state->client, IO_REG_PAD_CTRL_1_ADDR, + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_PAD_CTRL_1_ADDR, ADV_REG_SETFIELD(1, IO_PDN_INT2) | ADV_REG_SETFIELD(1, IO_PDN_INT3) | ADV_REG_SETFIELD(1, IO_INV_LLC) | ADV_REG_SETFIELD(AD_MID_DRIVE_STRNGTH, IO_DRV_LLC_PAD)); - ret |= adv7481_wr_byte(state->client, IO_REG_INT1_CONF_ADDR, + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_INT1_CONF_ADDR, ADV_REG_SETFIELD(AD_ACTIVE_UNTIL_CLR, IO_INTRQ_DUR_SEL) | ADV_REG_SETFIELD(AD_OP_DRIVE_LOW, IO_INTRQ_OP_SEL)); - ret |= adv7481_wr_byte(state->client, IO_REG_INT2_CONF_ADDR, + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_INT2_CONF_ADDR, ADV_REG_SETFIELD(1, IO_CP_LOCK_UNLOCK_EDGE_SEL)); - ret |= adv7481_wr_byte(state->client, IO_REG_DATAPATH_INT_MASKB_ADDR, + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_DATAPATH_INT_MASKB_ADDR, ADV_REG_SETFIELD(1, IO_CP_LOCK_CP_MB1) | ADV_REG_SETFIELD(1, IO_CP_UNLOCK_CP_MB1) | ADV_REG_SETFIELD(1, IO_VMUTE_REQUEST_HDMI_MB1) | ADV_REG_SETFIELD(1, IO_INT_SD_MB1)); - /* Set hpa */ - ret |= adv7481_wr_byte(state->client, IO_HDMI_LVL_INT_MASKB_3_ADDR, - ADV_REG_SETFIELD(1, IO_CABLE_DET_A_MB1)); + /* Set cable detect */ + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_HDMI_LVL_INT_MASKB_3_ADDR, + ADV_REG_SETFIELD(1, IO_CABLE_DET_A_MB1) | + ADV_REG_SETFIELD(1, IO_V_LOCKED_MB1) | + ADV_REG_SETFIELD(1, IO_DE_REGEN_LCK_MB1)); if (ret) pr_err("%s: Failed %d to setup interrupt regs\n", @@ -262,6 +365,20 @@ static int adv7481_set_irq(struct adv7481_state *state) return ret; } +static int adv7481_reset_irq(struct adv7481_state *state) +{ + int ret = 0; + + disable_irq(state->irq); + + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_DATAPATH_INT_MASKB_ADDR, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_HDMI_LVL_INT_MASKB_3_ADDR, 0x00); + + return ret; +} + static int adv7481_set_edid(struct adv7481_state *state) { int i; @@ -269,24 +386,27 @@ static int adv7481_set_edid(struct adv7481_state *state) uint8_t edid_state; /* Enable Manual Control of EDID on Port A */ - ret |= adv7481_wr_byte(state->i2c_rep, 0x74, 0x01); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_rep_addr, 0x74, + 0x01); /* Disable Auto Enable of EDID */ - ret |= adv7481_wr_byte(state->i2c_rep, 0x7A, 0x08); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_rep_addr, 0x7A, + 0x08); /* Set Primary EDID Size to 256 Bytes */ - ret |= adv7481_wr_byte(state->i2c_rep, 0x70, 0x20); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_rep_addr, 0x70, + 0x20); /* * Readback EDID enable state after a combination of manual * and automatic functions */ - edid_state = adv7481_rd_byte(state->i2c_rep, + edid_state = adv7481_rd_byte(&state->i2c_client, state->i2c_rep_addr, HDMI_REG_RO_EDID_DEBUG_2_ADDR); pr_debug("%s: Readback EDID enable state: 0x%x\n", __func__, edid_state); for (i = 0; i < ADV7481_EDID_SIZE; i++) { - ret |= adv7481_wr_byte(state->i2c_edid, i, - adv7481_default_edid_data[i]); + ret |= adv7481_wr_byte(&state->i2c_client, + state->i2c_edid_addr, i, adv7481_default_edid_data[i]); } return ret; @@ -304,43 +424,132 @@ static irqreturn_t adv7481_irq(int irq, void *dev) static void adv7481_irq_delay_work(struct work_struct *work) { struct adv7481_state *state; - uint8_t status; + uint8_t int_raw_status; + uint8_t int_status; + uint8_t raw_status; state = container_of(work, struct adv7481_state, irq_delayed_work.work); mutex_lock(&state->mutex); - /* workaround for irq trigger */ - status = adv7481_rd_byte(state->client, + /* Read raw irq status register */ + int_raw_status = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, IO_REG_INT_RAW_STATUS_ADDR); pr_debug("%s: dev: %d got int raw status: 0x%x\n", __func__, - state->device_num, status); + state->device_num, int_raw_status); + state->cec_detected = ADV_REG_GETFIELD(int_raw_status, IO_INT_CEC_ST); - status = adv7481_rd_byte(state->client, - IO_REG_DATAPATH_INT_STATUS_ADDR); + if (ADV_REG_GETFIELD(int_raw_status, IO_INTRQ1_RAW)) { + int lock_status = -1; + struct v4l2_event event = {0}; + int *ptr = (int *)event.u.data; - pr_debug("%s: dev: %d got datapath int status: 0x%x\n", __func__, - state->device_num, status); + pr_debug("%s: dev: %d got intrq1_raw\n", __func__, + state->device_num); + int_status = adv7481_rd_byte(&state->i2c_client, + state->i2c_io_addr, + IO_REG_DATAPATH_INT_STATUS_ADDR); - adv7481_wr_byte(state->client, - IO_REG_DATAPATH_INT_CLEAR_ADDR, status); + raw_status = adv7481_rd_byte(&state->i2c_client, + state->i2c_io_addr, + IO_REG_DATAPATH_RAW_STATUS_ADDR); - status = adv7481_rd_byte(state->client, - IO_REG_DATAPATH_RAW_STATUS_ADDR); + adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_DATAPATH_INT_CLEAR_ADDR, int_status); - pr_debug("%s: dev: %d got datapath rawstatus: 0x%x\n", __func__, - state->device_num, status); + pr_debug("%s: dev: %d got datapath int status: 0x%x\n", + __func__, state->device_num, int_status); - status = adv7481_rd_byte(state->client, - IO_HDMI_LVL_INT_STATUS_3_ADDR); + pr_debug("%s: dev: %d got datapath raw status: 0x%x\n", + __func__, state->device_num, raw_status); - pr_debug("%s: dev: %d got hdmi lvl int status 3: 0x%x\n", __func__, - state->device_num, status); + if (ADV_REG_GETFIELD(int_status, IO_CP_LOCK_CP_ST) && + ADV_REG_GETFIELD(raw_status, IO_CP_LOCK_CP_RAW)) { + lock_status = 0; + pr_debug( + "%s: set lock_status IO_CP_LOCK_CP_RAW: 0x%x\n", + __func__, lock_status); + } + if (ADV_REG_GETFIELD(int_status, IO_CP_UNLOCK_CP_ST) && + ADV_REG_GETFIELD(raw_status, IO_CP_UNLOCK_CP_RAW)) { + lock_status = 1; + pr_debug( + "%s: set lock_status IO_CP_UNLOCK_CP_RAW: 0x%x\n", + __func__, lock_status); + } + if (lock_status >= 0) { + ptr[0] = adv7481_inp_to_ba(state->mode); + ptr[1] = lock_status; + event.type = lock_status ? + V4L2_EVENT_MSM_BA_SIGNAL_LOST_LOCK : + V4L2_EVENT_MSM_BA_SIGNAL_IN_LOCK; + v4l2_subdev_notify(&state->sd, + event.type, &event); + } + } - adv7481_wr_byte(state->client, - IO_HDMI_LVL_INT_CLEAR_3_ADDR, status); + if (ADV_REG_GETFIELD(int_raw_status, IO_INT_HDMI_ST)) { + int cable_detected = 0; + struct v4l2_event event = {0}; + int *ptr = (int *)event.u.data; + + ptr[0] = adv7481_inp_to_ba(state->mode); + + pr_debug("%s: dev: %d got int_hdmi_st\n", __func__, + state->device_num); + + int_status = adv7481_rd_byte(&state->i2c_client, + state->i2c_io_addr, + IO_HDMI_LVL_INT_STATUS_3_ADDR); + + raw_status = adv7481_rd_byte(&state->i2c_client, + state->i2c_io_addr, + IO_HDMI_LVL_RAW_STATUS_3_ADDR); + + pr_debug("%s: dev: %d got hdmi lvl int status 3: 0x%x\n", + __func__, state->device_num, int_status); + pr_debug("%s: dev: %d got hdmi lvl raw status 3: 0x%x\n", + __func__, state->device_num, raw_status); + + + if (ADV_REG_GETFIELD(int_status, IO_CABLE_DET_A_ST)) { + cable_detected = ADV_REG_GETFIELD(raw_status, + IO_CABLE_DET_A_RAW); + pr_debug("%s: set cable_detected: 0x%x\n", + __func__, cable_detected); + ptr[1] = cable_detected; + event.type = V4L2_EVENT_MSM_BA_CABLE_DETECT; + v4l2_subdev_notify(&state->sd, + event.type, &event); + } + /* Assumption is that vertical sync int + * is the last one to come + */ + if (ADV_REG_GETFIELD(int_status, IO_V_LOCKED_ST)) { + if (ADV_REG_GETFIELD(raw_status, + IO_TMDSPLL_LCK_A_RAW) && + ADV_REG_GETFIELD(raw_status, + IO_V_LOCKED_RAW) && + ADV_REG_GETFIELD(raw_status, + IO_DE_REGEN_LCK_RAW)) { + pr_debug("%s: port settings changed\n", + __func__); + event.type = + V4L2_EVENT_MSM_BA_PORT_SETTINGS_CHANGED; + v4l2_subdev_notify(&state->sd, + event.type, &event); + } + } + } + /* Clear all other interrupts */ + adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_HDMI_LVL_INT_CLEAR_1_ADDR, 0xFF); + adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_HDMI_LVL_INT_CLEAR_2_ADDR, 0xFF); + adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_HDMI_LVL_INT_CLEAR_3_ADDR, 0xFF); mutex_unlock(&state->mutex); } @@ -350,110 +559,100 @@ static int adv7481_cec_wakeup(struct adv7481_state *state, bool enable) uint8_t val; int ret = 0; - val = adv7481_rd_byte(state->client, + val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, IO_REG_PWR_DN2_XTAL_HIGH_ADDR); val = ADV_REG_GETFIELD(val, IO_PROG_XTAL_FREQ_HIGH); if (enable) { /* CEC wake up enabled in power-down mode */ val |= ADV_REG_SETFIELD(1, IO_CTRL_CEC_WAKE_UP_PWRDN2B) | ADV_REG_SETFIELD(0, IO_CTRL_CEC_WAKE_UP_PWRDNB); - ret = adv7481_wr_byte(state->client, + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, IO_REG_PWR_DN2_XTAL_HIGH_ADDR, val); } else { /* CEC wake up disabled in power-down mode */ val |= ADV_REG_SETFIELD(0, IO_CTRL_CEC_WAKE_UP_PWRDN2B) | ADV_REG_SETFIELD(1, IO_CTRL_CEC_WAKE_UP_PWRDNB); - ret = adv7481_wr_byte(state->client, + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, IO_REG_PWR_DN2_XTAL_HIGH_ADDR, val); } return ret; } /* Initialize adv7481 I2C Settings */ -static int adv7481_dev_init(struct adv7481_state *state, - struct i2c_client *client) +static int adv7481_dev_init(struct adv7481_state *state) { + uint16_t chip_rev_id; int ret; mutex_lock(&state->mutex); /* Soft reset */ - ret = adv7481_wr_byte(state->client, - IO_REG_MAIN_RST_ADDR, IO_REG_MAIN_RST_VALUE); + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_MAIN_RST_ADDR, IO_REG_MAIN_RST_VALUE); /* Delay required following I2C reset and I2C transactions */ - usleep_range(I2C_SW_RST_DELAY, I2C_SW_RST_DELAY+1000); + usleep_range(I2C_SW_RST_DELAY, I2C_SW_RST_DELAY + 1000); + + chip_rev_id = adv7481_rd_word(&state->i2c_client, state->i2c_io_addr, + IO_REG_CHIP_REV_ID_1_ADDR); + pr_debug("%s: ADV7481 chip rev id: 0x%x", __func__, chip_rev_id); /* Disable CEC wake up in power-down mode */ ret |= adv7481_cec_wakeup(state, 0); /* Setting Vid_Std to 720x480p60 */ - ret |= adv7481_wr_byte(state->client, - IO_REG_CP_VID_STD_ADDR, 0x4A); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_CP_VID_STD_ADDR, 0x4A); /* Configure I2C Maps and I2C Communication Settings */ /* io_reg_f2 I2C Auto Increment */ - ret |= adv7481_wr_byte(state->client, IO_REG_I2C_CFG_ADDR, - IO_REG_I2C_AUTOINC_EN_REG_VALUE); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_I2C_CFG_ADDR, IO_REG_I2C_AUTOINC_EN_REG_VALUE); /* DPLL Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_DPLL_ADDR, - IO_REG_DPLL_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_DPLL_ADDR, IO_REG_DPLL_SADDR); /* CP Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_CP_ADDR, - IO_REG_CP_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_CP_ADDR, IO_REG_CP_SADDR); /* HDMI RX Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_HDMI_ADDR, - IO_REG_HDMI_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_HDMI_ADDR, IO_REG_HDMI_SADDR); /* EDID Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_EDID_ADDR, - IO_REG_EDID_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_EDID_ADDR, IO_REG_EDID_SADDR); /* HDMI RX Repeater Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_HDMI_REP_ADDR, - IO_REG_HDMI_REP_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_HDMI_REP_ADDR, IO_REG_HDMI_REP_SADDR); /* HDMI RX Info-frame Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_HDMI_INF_ADDR, - IO_REG_HDMI_INF_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_HDMI_INF_ADDR, IO_REG_HDMI_INF_SADDR); /* CBUS Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_CBUS_ADDR, - IO_REG_CBUS_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_CBUS_ADDR, IO_REG_CBUS_SADDR); /* CEC Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_CEC_ADDR, - IO_REG_CEC_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_CEC_ADDR, IO_REG_CEC_SADDR); /* SDP Main Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_SDP_ADDR, - IO_REG_SDP_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_SDP_ADDR, IO_REG_SDP_SADDR); /* CSI-TXB Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_CSI_TXB_ADDR, - IO_REG_CSI_TXB_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_CSI_TXB_ADDR, IO_REG_CSI_TXB_SADDR); /* CSI-TXA Map Address */ - ret |= adv7481_wr_byte(state->client, IO_REG_CSI_TXA_ADDR, - IO_REG_CSI_TXA_SADDR); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_CSI_TXA_ADDR, IO_REG_CSI_TXA_SADDR); if (ret) { pr_err("%s: Failed dev init %d\n", __func__, ret); goto err_exit; } /* Configure i2c clients */ - state->i2c_csi_txa = i2c_new_dummy(client->adapter, - IO_REG_CSI_TXA_SADDR >> 1); - state->i2c_csi_txb = i2c_new_dummy(client->adapter, - IO_REG_CSI_TXB_SADDR >> 1); - state->i2c_cp = i2c_new_dummy(client->adapter, - IO_REG_CP_SADDR >> 1); - state->i2c_hdmi = i2c_new_dummy(client->adapter, - IO_REG_HDMI_SADDR >> 1); - state->i2c_edid = i2c_new_dummy(client->adapter, - IO_REG_EDID_SADDR >> 1); - state->i2c_sdp = i2c_new_dummy(client->adapter, - IO_REG_SDP_SADDR >> 1); - state->i2c_rep = i2c_new_dummy(client->adapter, - IO_REG_HDMI_REP_SADDR >> 1); - - if (!state->i2c_csi_txa || !state->i2c_csi_txb || !state->i2c_cp || - !state->i2c_sdp || !state->i2c_hdmi || !state->i2c_edid || - !state->i2c_rep) { - pr_err("%s: Additional I2C Client Fail\n", __func__); - ret = -EFAULT; - goto err_exit; - } + state->i2c_csi_txa_addr = IO_REG_CSI_TXA_SADDR >> 1; + state->i2c_csi_txb_addr = IO_REG_CSI_TXB_SADDR >> 1; + state->i2c_cp_addr = IO_REG_CP_SADDR >> 1; + state->i2c_hdmi_addr = IO_REG_HDMI_SADDR >> 1; + state->i2c_edid_addr = IO_REG_EDID_SADDR >> 1; + state->i2c_sdp_addr = IO_REG_SDP_SADDR >> 1; + state->i2c_rep_addr = IO_REG_HDMI_REP_SADDR >> 1; + state->i2c_cbus_addr = IO_REG_CBUS_SADDR >> 1; ret = adv7481_set_edid(state); ret |= adv7481_set_irq(state); @@ -465,28 +664,27 @@ err_exit: } /* Initialize adv7481 hardware */ -static int adv7481_hw_init(struct adv7481_platform_data *pdata, - struct adv7481_state *state) +static int adv7481_hw_init(struct adv7481_state *state) { int ret = 0; - if (!pdata) { - pr_err("%s: PDATA is NULL\n", __func__); - return -EFAULT; - } - mutex_lock(&state->mutex); - if (gpio_is_valid(pdata->rstb_gpio)) { - ret = gpio_request(pdata->rstb_gpio, "rstb_gpio"); - if (ret) { - pr_err("%s: Request GPIO Fail %d\n", __func__, ret); - goto err_exit; - } - ret = gpio_direction_output(pdata->rstb_gpio, 0); - usleep_range(GPIO_HW_DELAY_LOW, GPIO_HW_DELAY_LOW+1000); - ret = gpio_direction_output(pdata->rstb_gpio, 1); - usleep_range(GPIO_HW_DELAY_HI, GPIO_HW_DELAY_HI+1000); + /* Bring ADV7481 out of reset */ + ret = gpio_request_array(&state->gpio_array[ADV7481_GPIO_RST], 1); + if (ret < 0) { + pr_err("%s: Failed to request reset GPIO %d\n", __func__, ret); + goto err_exit; + } + if (gpio_is_valid(state->gpio_array[ADV7481_GPIO_RST].gpio)) { + ret |= gpio_direction_output( + state->gpio_array[ADV7481_GPIO_RST].gpio, 0); + usleep_range(GPIO_HW_RST_DELAY_LOW, GPIO_HW_RST_DELAY_LOW + + 1000); + ret |= gpio_direction_output( + state->gpio_array[ADV7481_GPIO_RST].gpio, 1); + usleep_range(GPIO_HW_RST_DELAY_HI, GPIO_HW_RST_DELAY_HI + + 1000); if (ret) { pr_err("%s: Set GPIO Fail %d\n", __func__, ret); goto err_exit; @@ -494,22 +692,21 @@ static int adv7481_hw_init(struct adv7481_platform_data *pdata, } /* Only setup IRQ1 for now... */ - if (gpio_is_valid(pdata->irq1_gpio)) { - ret = gpio_request(pdata->irq1_gpio, "irq_gpio"); - if (ret) { - pr_err("%s: Failed to request irq_gpio %d\n", - __func__, ret); - goto err_exit; - } - - ret = gpio_direction_input(pdata->irq1_gpio); + ret = gpio_request_array(&state->gpio_array[ADV7481_GPIO_INT1], 1); + if (ret < 0) { + pr_err("%s: Failed to request irq_gpio %d\n", __func__, ret); + goto err_exit; + } + if (gpio_is_valid(state->gpio_array[ADV7481_GPIO_INT1].gpio)) { + ret |= gpio_direction_input( + state->gpio_array[ADV7481_GPIO_INT1].gpio); if (ret) { pr_err("%s: Failed gpio_direction irq %d\n", __func__, ret); goto err_exit; } - - state->irq = gpio_to_irq(pdata->irq1_gpio); + state->irq = gpio_to_irq( + state->gpio_array[ADV7481_GPIO_INT1].gpio); if (state->irq) { ret = request_irq(state->irq, adv7481_irq, IRQF_ONESHOT | IRQF_TRIGGER_FALLING, @@ -519,18 +716,16 @@ static int adv7481_hw_init(struct adv7481_platform_data *pdata, __func__, ret); goto err_exit; } + /* disable irq until chip interrupts are programmed */ + disable_irq(state->irq); } else { pr_err("%s: Failed gpio_to_irq %d\n", __func__, ret); ret = -EINVAL; goto err_exit; } - - /* disable irq until chip interrupts are programmed */ - disable_irq(state->irq); - - INIT_DELAYED_WORK(&state->irq_delayed_work, - adv7481_irq_delay_work); } + INIT_DELAYED_WORK(&state->irq_delayed_work, + adv7481_irq_delay_work); err_exit: mutex_unlock(&state->mutex); @@ -548,31 +743,40 @@ static int adv7481_s_ctrl(struct v4l2_ctrl *ctrl) pr_debug("Enter %s: id = 0x%x\n", __func__, ctrl->id); switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - temp = adv7481_rd_byte(state->client, CP_REG_VID_ADJ); + temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_VID_ADJ); temp |= CP_CTR_VID_ADJ_EN; - ret = adv7481_wr_byte(state->client, CP_REG_VID_ADJ, temp); - ret |= adv7481_wr_byte(state->client, - CP_REG_BRIGHTNESS, ctrl->val); + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_VID_ADJ, temp); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_BRIGHTNESS, ctrl->val); break; case V4L2_CID_CONTRAST: - temp = adv7481_rd_byte(state->client, CP_REG_VID_ADJ); + temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_VID_ADJ); temp |= CP_CTR_VID_ADJ_EN; - ret = adv7481_wr_byte(state->client, CP_REG_VID_ADJ, temp); - ret |= adv7481_wr_byte(state->client, - CP_REG_CONTRAST, ctrl->val); + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_VID_ADJ, temp); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_CONTRAST, ctrl->val); break; case V4L2_CID_SATURATION: - temp = adv7481_rd_byte(state->client, CP_REG_VID_ADJ); + temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_VID_ADJ); temp |= CP_CTR_VID_ADJ_EN; - ret = adv7481_wr_byte(state->client, CP_REG_VID_ADJ, temp); - ret |= adv7481_wr_byte(state->client, - CP_REG_SATURATION, ctrl->val); + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_VID_ADJ, temp); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_SATURATION, ctrl->val); break; case V4L2_CID_HUE: - temp = adv7481_rd_byte(state->client, CP_REG_VID_ADJ); + temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_VID_ADJ); temp |= CP_CTR_VID_ADJ_EN; - ret = adv7481_wr_byte(state->client, CP_REG_VID_ADJ, temp); - ret |= adv7481_wr_byte(state->client, CP_REG_HUE, ctrl->val); + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_VID_ADJ, temp); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CP_REG_HUE, ctrl->val); break; default: break; @@ -611,6 +815,108 @@ static int adv7481_s_power(struct v4l2_subdev *sd, int on) return ret; } +static int adv7481_set_cec_logical_addr(struct adv7481_state *state, int *la) +{ + int rc = 0; + uint8_t val; + + if (!la) { + pr_err("%s: NULL pointer provided\n", __func__); + return -EINVAL; + } + + val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + CEC_REG_LOG_ADDR_MASK_ADDR); + if (ADV_REG_GETFIELD(val, CEC_REG_LOG_ADDR_MASK0)) { + val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + CEC_REG_LOGICAL_ADDRESS0_1_ADDR); + val = ADV_REG_RSTFIELD(val, CEC_REG_LOGICAL_ADDRESS0); + val |= ADV_REG_SETFIELD(*la, CEC_REG_LOGICAL_ADDRESS0); + rc = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CEC_REG_LOGICAL_ADDRESS0_1_ADDR, val); + } else if (ADV_REG_GETFIELD(val, CEC_REG_LOG_ADDR_MASK1)) { + val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + CEC_REG_LOGICAL_ADDRESS0_1_ADDR); + val = ADV_REG_RSTFIELD(val, CEC_REG_LOGICAL_ADDRESS1); + val |= ADV_REG_SETFIELD(*la, CEC_REG_LOGICAL_ADDRESS1); + rc = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CEC_REG_LOGICAL_ADDRESS0_1_ADDR, val); + } else if (ADV_REG_GETFIELD(val, CEC_REG_LOG_ADDR_MASK2)) { + val = ADV_REG_SETFIELD(*la, CEC_REG_LOGICAL_ADDRESS2); + rc = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CEC_REG_LOGICAL_ADDRESS2_ADDR, val); + } else { + pr_err("No cec logical address mask set\n"); + } + + return rc; +} + +static int adv7481_cec_powerup(struct adv7481_state *state, int *powerup) +{ + int rc = 0; + uint8_t val = 0; + + if (!powerup) { + pr_err("%s: NULL pointer provided\n", __func__); + return -EINVAL; + } + + pr_debug("%s: set power %d\n", __func__, *powerup); + + val = ADV_REG_SETFIELD(*powerup, CEC_REG_CEC_POWER_UP); + rc = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + CEC_REG_CEC_POWER_UP_ADDR, val); + + return rc; +} + +static long adv7481_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct adv7481_state *state = to_state(sd); + int *ret_val = arg; + long ret = 0; + int param = 0; + + pr_debug("Enter %s with command: 0x%x", __func__, cmd); + + if (!sd) + return -EINVAL; + + switch (cmd) { + case VIDIOC_HDMI_RX_CEC_S_LOGICAL: + ret = adv7481_set_cec_logical_addr(state, arg); + break; + case VIDIOC_HDMI_RX_CEC_CLEAR_LOGICAL: + ret = adv7481_set_cec_logical_addr(state, ¶m); + break; + case VIDIOC_HDMI_RX_CEC_G_PHYSICAL: + if (ret_val) { + *ret_val = 0; + } else { + pr_err("%s: NULL pointer provided\n", __func__); + ret = -EINVAL; + } + break; + case VIDIOC_HDMI_RX_CEC_G_CONNECTED: + if (ret_val) { + *ret_val = state->cec_detected; + } else { + pr_err("%s: NULL pointer provided\n", __func__); + ret = -EINVAL; + } + break; + case VIDIOC_HDMI_RX_CEC_S_ENABLE: + ret = adv7481_cec_powerup(state, arg); + break; + default: + pr_err("Not a typewriter! Command: 0x%x", cmd); + ret = -ENOTTY; + break; + } + return ret; +} + static int adv7481_get_sd_timings(struct adv7481_state *state, int *sd_standard) { int ret = 0; @@ -621,17 +927,16 @@ static int adv7481_get_sd_timings(struct adv7481_state *state, int *sd_standard) return -EINVAL; do { - sdp_stat = adv7481_rd_byte(state->i2c_sdp, - SDP_RO_MAIN_STATUS1_ADDR); + sdp_stat = adv7481_rd_byte(&state->i2c_client, + state->i2c_sdp_addr, SDP_RO_MAIN_STATUS1_ADDR); usleep_range(SDP_MIN_SLEEP, SDP_MAX_SLEEP); timeout++; - sdp_stat2 = adv7481_rd_byte(state->i2c_sdp, - SDP_RO_MAIN_STATUS1_ADDR); + sdp_stat2 = adv7481_rd_byte(&state->i2c_client, + state->i2c_sdp_addr, SDP_RO_MAIN_STATUS1_ADDR); } while ((sdp_stat != sdp_stat2) && (timeout < SDP_NUM_TRIES)); if (sdp_stat != sdp_stat2) { - pr_err("%s(%d), adv7481 SDP status unstable: 1\n", - __func__, __LINE__); + pr_err("%s, adv7481 SDP status unstable: 1\n", __func__); return -ETIMEDOUT; } @@ -681,22 +986,35 @@ static int adv7481_set_cvbs_mode(struct adv7481_state *state) pr_debug("Enter %s\n", __func__); state->mode = ADV7481_IP_CVBS_1; /* cvbs video settings ntsc etc */ - ret = adv7481_wr_byte(state->client, 0x00, 0x30); - ret |= adv7481_wr_byte(state->i2c_sdp, 0x0f, 0x00); - ret |= adv7481_wr_byte(state->i2c_sdp, 0x00, 0x00); - ret |= adv7481_wr_byte(state->i2c_sdp, 0x03, 0x42); - ret |= adv7481_wr_byte(state->i2c_sdp, 0x04, 0x07); - ret |= adv7481_wr_byte(state->i2c_sdp, 0x13, 0x00); - ret |= adv7481_wr_byte(state->i2c_sdp, 0x17, 0x41); - ret |= adv7481_wr_byte(state->i2c_sdp, 0x31, 0x12); - ret |= adv7481_wr_byte(state->i2c_sdp, 0x52, 0xcd); - ret |= adv7481_wr_byte(state->i2c_sdp, 0x0e, 0xff); - val = adv7481_rd_byte(state->client, IO_REG_CSI_PIX_EN_SEL_ADDR); + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + 0x00, 0x30); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x0f, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x00, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x03, 0x42); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x04, 0x07); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x13, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x17, 0x41); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x31, 0x12); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x52, 0xcd); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x0e, 0xff); + val = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_CSI_PIX_EN_SEL_ADDR); /* Output of SD core routed to MIPI CSI 4-lane Tx */ val |= ADV_REG_SETFIELD(0x10, IO_CTRL_CSI4_IN_SEL); - ret |= adv7481_wr_byte(state->client, IO_REG_CSI_PIX_EN_SEL_ADDR, val); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_CSI_PIX_EN_SEL_ADDR, val); /* Enable autodetect */ - ret |= adv7481_wr_byte(state->i2c_sdp, 0x0e, 0x81); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, + 0x0e, 0x81); return ret; } @@ -713,69 +1031,101 @@ static int adv7481_set_hdmi_mode(struct adv7481_state *state) * YUV 422 out via TxA CSI: 4-Lane */ /* Disable chip powerdown & Enable HDMI Rx block */ - temp = adv7481_rd_byte(state->client, IO_REG_PWR_DOWN_CTRL_ADDR); + temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_PWR_DOWN_CTRL_ADDR); val = ADV_REG_SETFIELD(1, IO_CTRL_RX_EN) | ADV_REG_SETFIELD(0, IO_CTRL_RX_PWDN) | ADV_REG_SETFIELD(0, IO_CTRL_XTAL_PWDN) | ADV_REG_SETFIELD(0, IO_CTRL_CORE_PWDN) | ADV_REG_SETFIELD(0, IO_CTRL_MASTER_PWDN); - ret = adv7481_wr_byte(state->client, IO_REG_PWR_DOWN_CTRL_ADDR, val); + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_PWR_DOWN_CTRL_ADDR, val); /* SDR mode */ - ret |= adv7481_wr_byte(state->client, 0x11, 0x48); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + 0x11, 0x48); /* Set CP core to YUV out */ - ret |= adv7481_wr_byte(state->client, 0x04, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + 0x04, 0x00); /* Set CP core to SDR 422 */ - ret |= adv7481_wr_byte(state->client, 0x12, 0xF2); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + 0x12, 0xF2); /* Saturate both Luma and Chroma values to 254 */ - ret |= adv7481_wr_byte(state->client, 0x17, 0x80); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + 0x17, 0x80); /* Set CP core to enable AV codes */ - ret |= adv7481_wr_byte(state->client, 0x03, 0x86); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + 0x03, 0x86); /* ADI RS CP Core: */ - ret |= adv7481_wr_byte(state->i2c_cp, 0x7C, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_cp_addr, + 0x7C, 0x00); /* Set CP core Phase Adjustment */ - ret |= adv7481_wr_byte(state->client, 0x0C, 0xE0); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + 0x0C, 0xE0); /* LLC/PIX/SPI PINS TRISTATED AUD Outputs Enabled */ - ret |= adv7481_wr_byte(state->client, IO_PAD_CTRLS_ADDR, 0xDD); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_PAD_CTRLS_ADDR, 0xDD); /* Enable Tx A CSI 4-Lane & data from CP core */ val = ADV_REG_SETFIELD(1, IO_CTRL_CSI4_EN) | ADV_REG_SETFIELD(1, IO_CTRL_PIX_OUT_EN) | ADV_REG_SETFIELD(0, IO_CTRL_CSI4_IN_SEL); - ret |= adv7481_wr_byte(state->client, IO_REG_CSI_PIX_EN_SEL_ADDR, - val); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_CSI_PIX_EN_SEL_ADDR, val); /* start to configure HDMI Rx once io-map is configured */ /* Enable HDCP 1.1 */ - ret |= adv7481_wr_byte(state->i2c_rep, 0x40, 0x83); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_rep_addr, + 0x40, 0x83); /* Foreground Channel = A */ - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x00, 0x08); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x00, 0x08); /* ADI Required Write */ - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x98, 0xFF); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x99, 0xA3); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x9A, 0x00); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x9B, 0x0A); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x9D, 0x40); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0xCB, 0x09); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x98, 0xFF); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x99, 0xA3); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x9A, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x9B, 0x0A); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x9D, 0x40); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0xCB, 0x09); /* ADI RS */ - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x3D, 0x10); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x3E, 0x7B); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x3F, 0x5E); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x4E, 0xFE); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x4F, 0x18); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x57, 0xA3); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x58, 0x04); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x85, 0x10); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x3D, 0x10); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x3E, 0x7B); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x3F, 0x5E); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x4E, 0xFE); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x4F, 0x18); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x57, 0xA3); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x58, 0x04); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x85, 0x10); /* Enable All Terminations */ - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x83, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x83, 0x00); /* ADI RS */ - ret |= adv7481_wr_byte(state->i2c_hdmi, 0xA3, 0x01); - ret |= adv7481_wr_byte(state->i2c_hdmi, 0xBE, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0xA3, 0x01); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0xBE, 0x00); /* HPA Manual Enable */ - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x6C, 0x01); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x6C, 0x01); /* HPA Asserted */ - ret |= adv7481_wr_byte(state->i2c_hdmi, 0xF8, 0x01); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0xF8, 0x01); /* Audio Mute Speed Set to Fastest (Smallest Step Size) */ - ret |= adv7481_wr_byte(state->i2c_hdmi, 0x0F, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, + 0x0F, 0x00); return ret; } @@ -860,7 +1210,7 @@ static int adv7481_set_ip_mode(struct adv7481_state *state, int input) } static int adv7481_set_op_src(struct adv7481_state *state, - int output, int input) + int output, int input) { int ret = 0; int temp = 0; @@ -897,10 +1247,11 @@ static int adv7481_set_op_src(struct adv7481_state *state, default: ret = -EINVAL; } - temp = adv7481_rd_byte(state->client, + temp = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, IO_REG_PWR_DOWN_CTRL_ADDR); temp |= val; - adv7481_wr_byte(state->client, IO_REG_PWR_DOWN_CTRL_ADDR, temp); + adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, + IO_REG_PWR_DOWN_CTRL_ADDR, temp); state->csia_src = input; break; case ADV7481_OP_CSIB: @@ -915,11 +1266,11 @@ static int adv7481_set_op_src(struct adv7481_state *state, return ret; } -static u32 ba_inp_to_adv7481(u32 input) +static u32 ba_inp_to_adv7481(u32 ba_input) { u32 adv_input = ADV7481_IP_HDMI; - switch (input) { + switch (ba_input) { case BA_IP_CVBS_0: adv_input = ADV7481_IP_CVBS_1; break; @@ -954,6 +1305,42 @@ static u32 ba_inp_to_adv7481(u32 input) return adv_input; } +static u32 adv7481_inp_to_ba(u32 adv_input) +{ + u32 ba_input = BA_IP_HDMI_1; + + switch (adv_input) { + case ADV7481_IP_CVBS_1: + ba_input = BA_IP_CVBS_0; + break; + case ADV7481_IP_CVBS_2: + ba_input = BA_IP_CVBS_1; + break; + case ADV7481_IP_CVBS_3: + ba_input = BA_IP_CVBS_2; + break; + case ADV7481_IP_CVBS_4: + ba_input = BA_IP_CVBS_3; + break; + case ADV7481_IP_CVBS_5: + ba_input = BA_IP_CVBS_4; + break; + case ADV7481_IP_CVBS_6: + ba_input = BA_IP_CVBS_5; + break; + case ADV7481_IP_HDMI: + ba_input = BA_IP_HDMI_1; + break; + case ADV7481_IP_TTL: + ba_input = BA_IP_TTL; + break; + default: + ba_input = BA_IP_HDMI_1; + break; + } + return ba_input; +} + static int adv7481_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, u32 config) { @@ -986,6 +1373,27 @@ unlock_exit: return ret; } +static bool adv7481_is_timing_locked(struct adv7481_state *state) +{ + bool ret = false; + int val1 = 0; + int val2 = 0; + + /* Check Timing Lock IO Map Status3:0x71[0] && 0x71[1] && 0x71[7] */ + val1 = adv7481_rd_byte(&state->i2c_client, state->i2c_io_addr, + IO_HDMI_LVL_RAW_STATUS_3_ADDR); + val2 = adv7481_rd_byte(&state->i2c_client, state->i2c_cp_addr, + CP_REG_STDI_CH_ADDR); + + if (ADV_REG_GETFIELD(val1, IO_DE_REGEN_LCK_RAW) && + ADV_REG_GETFIELD(val1, IO_V_LOCKED_RAW) && + ADV_REG_GETFIELD(val1, IO_TMDSPLL_LCK_A_RAW) && + ADV_REG_GETFIELD(val2, CP_STDI_DVALID_CH1)) + ret = true; + + return ret; +} + static int adv7481_get_hdmi_timings(struct adv7481_state *state, struct adv7481_vid_params *vid_params, struct adv7481_hdmi_params *hdmi_params) @@ -998,13 +1406,15 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state, pr_debug("Enter %s\n", __func__); /* Check TMDS PLL Lock and Frequency */ - temp1 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_HDMI_PARAM4_ADDR); + temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, + HDMI_REG_HDMI_PARAM4_ADDR); hdmi_params->pll_lock = ADV_REG_GETFIELD(temp1, HDMI_REG_TMDS_PLL_LOCKED); if (hdmi_params->pll_lock) { - temp1 = adv7481_rd_byte(state->i2c_hdmi, - HDMI_REG_TMDS_FREQ_ADDR); - temp2 = adv7481_rd_byte(state->i2c_hdmi, + temp1 = adv7481_rd_byte(&state->i2c_client, + state->i2c_hdmi_addr, HDMI_REG_TMDS_FREQ_ADDR); + temp2 = adv7481_rd_byte(&state->i2c_client, + state->i2c_hdmi_addr, HDMI_REG_TMDS_FREQ_FRAC_ADDR); hdmi_params->tmds_freq = ADV_REG_GETFIELD(temp1, HDMI_REG_TMDS_FREQ); @@ -1015,34 +1425,29 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state, hdmi_params->tmds_freq += ADV_REG_GETFIELD(temp2, HDMI_REG_TMDS_FREQ_FRAC)*ONE_MHZ_TO_HZ/128; } else { - pr_err("%s: PLL not locked return EBUSY\n", __func__); - return -EBUSY; + pr_err("%s(%d): PLL not locked return EBUSY\n", + __func__, __LINE__); + ret = -EBUSY; + goto set_default; } - /* Check Timing Lock IO Map Status3:0x71[0] && 0x71[1] && 0x71[7] */ + /* Check Timing Lock */ do { - temp1 = adv7481_rd_byte(state->client, - IO_HDMI_LVL_RAW_STATUS_3_ADDR); - temp2 = adv7481_rd_byte(state->i2c_cp, - CP_REG_STDI_CH_ADDR); - - if (ADV_REG_GETFIELD(temp1, IO_DE_REGEN_LCK_RAW) && - ADV_REG_GETFIELD(temp1, IO_V_LOCKED_RAW) && - ADV_REG_GETFIELD(temp1, IO_TMDSPLL_LCK_A_RAW) && - ADV_REG_GETFIELD(temp2, CP_STDI_DVALID_CH1)) + if (adv7481_is_timing_locked(state)) break; count++; usleep_range(LOCK_MIN_SLEEP, LOCK_MAX_SLEEP); } while (count < LOCK_NUM_TRIES); if (count >= LOCK_NUM_TRIES) { - pr_err("%s(%d), adv7481 HDMI DE regeneration block NOT Locked: 0x%x", - __func__, __LINE__, temp1); + pr_err("%s(%d), HDMI DE regeneration block NOT Locked\n", + __func__, __LINE__); } /* Check Timing Lock HDMI Map V:0x07[7], H:0x7[5] */ do { - temp1 = adv7481_rd_byte(state->i2c_hdmi, + temp1 = adv7481_rd_byte(&state->i2c_client, + state->i2c_hdmi_addr, HDMI_REG_LINE_WIDTH_1_ADDR); if (ADV_REG_GETFIELD(temp1, HDMI_VERT_FILTER_LOCKED) && @@ -1059,7 +1464,8 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state, } /* Check HDMI Parameters */ - temp1 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_FIELD1_HEIGHT1_ADDR); + temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, + HDMI_REG_FIELD1_HEIGHT1_ADDR); hdmi_params->color_depth = ADV_REG_GETFIELD(temp1, HDMI_REG_DEEP_COLOR_MODE); @@ -1068,22 +1474,25 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state, HDMI_REG_HDMI_INTERLACED); fieldfactor = (vid_params->intrlcd == 1) ? 2 : 1; - temp1 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_HDMI_PARAM5_ADDR); + temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, + HDMI_REG_HDMI_PARAM5_ADDR); hdmi_params->pix_rep = ADV_REG_GETFIELD(temp1, HDMI_REG_PIXEL_REPETITION); /* Get Active Timing Data HDMI Map H:0x07[4:0] + 0x08[7:0] */ - temp1 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_LINE_WIDTH_1_ADDR); - temp2 = adv7481_rd_byte(state->i2c_hdmi, HDMI_REG_LINE_WIDTH_2_ADDR); + temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, + HDMI_REG_LINE_WIDTH_1_ADDR); + temp2 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, + HDMI_REG_LINE_WIDTH_2_ADDR); vid_params->act_pix = (((ADV_REG_GETFIELD(temp1, HDMI_REG_LINE_WIDTH_1) << 8) & 0x1F00) | ADV_REG_GETFIELD(temp2, HDMI_REG_LINE_WIDTH_2)); /* Get Total Timing Data HDMI Map H:0x1E[5:0] + 0x1F[7:0] */ - temp1 = adv7481_rd_byte(state->i2c_hdmi, + temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_TOTAL_LINE_WIDTH_1_ADDR); - temp2 = adv7481_rd_byte(state->i2c_hdmi, + temp2 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_TOTAL_LINE_WIDTH_2_ADDR); vid_params->tot_pix = (((ADV_REG_GETFIELD(temp1, HDMI_REG_TOTAL_LINE_WIDTH_1) << 8) & 0x3F00) | @@ -1091,9 +1500,9 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state, HDMI_REG_TOTAL_LINE_WIDTH_2)); /* Get Active Timing Data HDMI Map V:0x09[4:0] + 0x0A[7:0] */ - temp1 = adv7481_rd_byte(state->i2c_hdmi, + temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_FIELD0_HEIGHT_1_ADDR); - temp2 = adv7481_rd_byte(state->i2c_hdmi, + temp2 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_FIELD0_HEIGHT_2_ADDR); vid_params->act_lines = (((ADV_REG_GETFIELD(temp1, HDMI_REG_FIELD0_HEIGHT_1) << 8) & 0x1F00) | @@ -1101,9 +1510,9 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state, HDMI_REG_FIELD0_HEIGHT_2)); /* Get Total Timing Data HDMI Map V:0x26[5:0] + 0x27[7:0] */ - temp1 = adv7481_rd_byte(state->i2c_hdmi, + temp1 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_FIELD0_TOTAL_HEIGHT_1_ADDR); - temp2 = adv7481_rd_byte(state->i2c_hdmi, + temp2 = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_FIELD0_TOTAL_HEIGHT_2_ADDR); vid_params->tot_lines = (((ADV_REG_GETFIELD(temp1, HDMI_REG_FIELD0_TOT_HEIGHT_1) << 8) & 0x3F00) | @@ -1139,6 +1548,18 @@ static int adv7481_get_hdmi_timings(struct adv7481_state *state, (hdmi_params->pix_rep + 1)); } +set_default: + if (ret) { + pr_debug("%s(%d), error %d resort to default fmt\n", + __func__, __LINE__, ret); + vid_params->act_pix = MAX_DEFAULT_WIDTH; + vid_params->act_lines = MAX_DEFAULT_HEIGHT; + vid_params->fr_rate = MAX_DEFAULT_FRAME_RATE; + vid_params->pix_clk = MAX_DEFAULT_PIX_CLK_HZ; + vid_params->intrlcd = 0; + ret = 0; + } + pr_debug("%s(%d), adv7481 TMDS Resolution: %d x %d @ %d fps\n", __func__, __LINE__, vid_params->act_pix, vid_params->act_lines, @@ -1170,15 +1591,22 @@ static int adv7481_query_dv_timings(struct v4l2_subdev *sd, switch (state->mode) { case ADV7481_IP_HDMI: case ADV7481_IP_CVBS_1_HDMI_SIM: - adv7481_get_hdmi_timings(state, &vid_params, &hdmi_params); - timings->type = V4L2_DV_BT_656_1120; - bt_timings->width = vid_params.act_pix; - bt_timings->height = vid_params.act_lines; - bt_timings->pixelclock = vid_params.pix_clk; - bt_timings->interlaced = vid_params.intrlcd ? + ret = adv7481_get_hdmi_timings(state, &vid_params, + &hdmi_params); + if (!ret) { + timings->type = V4L2_DV_BT_656_1120; + bt_timings->width = vid_params.act_pix; + bt_timings->height = vid_params.act_lines; + bt_timings->pixelclock = vid_params.pix_clk; + bt_timings->interlaced = vid_params.intrlcd ? V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE; - if (bt_timings->interlaced == V4L2_DV_INTERLACED) - bt_timings->height /= 2; + if (bt_timings->interlaced == V4L2_DV_INTERLACED) + bt_timings->height /= 2; + } else { + pr_err( + "%s: Error in adv7481_get_hdmi_timings. ret %d\n", + __func__, ret); + } break; default: return -EINVAL; @@ -1195,7 +1623,8 @@ static int adv7481_query_sd_std(struct v4l2_subdev *sd, v4l2_std_id *std) uint8_t tStatus = 0x0; pr_debug("Enter %s\n", __func__); - tStatus = adv7481_rd_byte(state->i2c_sdp, SDP_RO_MAIN_STATUS1_ADDR); + tStatus = adv7481_rd_byte(&state->i2c_client, state->i2c_sdp_addr, + SDP_RO_MAIN_STATUS1_ADDR); if (!ADV_REG_GETFIELD(tStatus, SDP_RO_MAIN_IN_LOCK)) pr_err("%s(%d), adv7481 SD Input NOT Locked: 0x%x\n", __func__, __LINE__, tStatus); @@ -1267,11 +1696,17 @@ static int adv7481_g_mbus_fmt(struct v4l2_subdev *sd, switch (state->mode) { case ADV7481_IP_HDMI: case ADV7481_IP_CVBS_1_HDMI_SIM: - adv7481_get_hdmi_timings(state, &vid_params, &hdmi_params); - fmt->width = vid_params.act_pix; - fmt->height = vid_params.act_lines; - if (vid_params.intrlcd) - fmt->height /= 2; + ret = adv7481_get_hdmi_timings(state, &vid_params, + &hdmi_params); + if (!ret) { + fmt->width = vid_params.act_pix; + fmt->height = vid_params.act_lines; + if (vid_params.intrlcd) + fmt->height /= 2; + } else { + pr_err("%s: Error %d in adv7481_get_hdmi_timings\n", + __func__, ret); + } break; default: return -EINVAL; @@ -1290,17 +1725,17 @@ static int adv7481_set_audio_spdif(struct adv7481_state *state, if (on) { /* Configure I2S_SDATA output pin as an SPDIF output 0x6E[3] */ - val = adv7481_rd_byte(state->i2c_hdmi, + val = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_MUX_SPDIF_TO_I2S_ADDR); val |= ADV_REG_SETFIELD(1, HDMI_MUX_SPDIF_TO_I2S_EN); - ret = adv7481_wr_byte(state->i2c_hdmi, + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_MUX_SPDIF_TO_I2S_ADDR, val); } else { /* Configure I2S_SDATA output pin as an I2S output 0x6E[3] */ - val = adv7481_rd_byte(state->i2c_hdmi, + val = adv7481_rd_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_MUX_SPDIF_TO_I2S_ADDR); val &= ~ADV_REG_SETFIELD(1, HDMI_MUX_SPDIF_TO_I2S_EN); - ret = adv7481_wr_byte(state->i2c_hdmi, + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_hdmi_addr, HDMI_REG_MUX_SPDIF_TO_I2S_ADDR, val); } return ret; @@ -1310,40 +1745,42 @@ static int adv7481_csi_powerdown(struct adv7481_state *state, enum adv7481_output output) { int ret; - struct i2c_client *csi_map; + uint8_t csi_map; uint8_t val = 0; pr_debug("Enter %s for output: %d\n", __func__, output); /* Select CSI TX to configure data */ if (output == ADV7481_OP_CSIA) { - csi_map = state->i2c_csi_txa; + csi_map = state->i2c_csi_txa_addr; } else if (output == ADV7481_OP_CSIB) { - csi_map = state->i2c_csi_txb; + csi_map = state->i2c_csi_txb_addr; } else if (output == ADV7481_OP_TTL) { /* For now use TxA */ - csi_map = state->i2c_csi_txa; + csi_map = state->i2c_csi_txa_addr; } else { /* Default to TxA */ - csi_map = state->i2c_csi_txa; + csi_map = state->i2c_csi_txa_addr; } /* CSI Tx: power down DPHY */ - ret = adv7481_wr_byte(csi_map, CSI_REG_TX_DPHY_PWDN_ADDR, + ret = adv7481_wr_byte(&state->i2c_client, csi_map, + CSI_REG_TX_DPHY_PWDN_ADDR, ADV_REG_SETFIELD(1, CSI_CTRL_DPHY_PWDN)); /* ADI Required Write */ - ret |= adv7481_wr_byte(csi_map, 0x31, 0x82); - ret |= adv7481_wr_byte(csi_map, 0x1e, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x31, 0x82); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x1e, 0x00); /* CSI TxA: # Lane : Power Off */ val = ADV_REG_SETFIELD(1, CSI_CTRL_TX_PWRDN) | ADV_REG_SETFIELD(state->tx_lanes, CSI_CTRL_NUM_LANES); - ret |= adv7481_wr_byte(csi_map, CSI_REG_TX_CFG1_ADDR, val); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, + CSI_REG_TX_CFG1_ADDR, val); /* * ADI Recommended power down sequence * DPHY and CSI Tx A Power down Sequence * CSI TxA: MIPI PLL DIS */ - ret |= adv7481_wr_byte(csi_map, 0xda, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xda, 0x00); /* ADI Required Write */ - ret |= adv7481_wr_byte(csi_map, 0xc1, 0x3b); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xc1, 0x3b); pr_debug("Exit %s, ret: %d\n", __func__, ret); @@ -1354,7 +1791,7 @@ static int adv7481_csi_powerup(struct adv7481_state *state, enum adv7481_output output) { int ret; - struct i2c_client *csi_map; + uint8_t csi_map; uint8_t val = 0; uint8_t csi_sel = 0; @@ -1364,7 +1801,7 @@ static int adv7481_csi_powerup(struct adv7481_state *state, csi_sel = ADV_REG_SETFIELD(1, IO_CTRL_CSI4_EN) | ADV_REG_SETFIELD(1, IO_CTRL_PIX_OUT_EN) | ADV_REG_SETFIELD(0, IO_CTRL_CSI4_IN_SEL); - csi_map = state->i2c_csi_txa; + csi_map = state->i2c_csi_txa_addr; } else if (output == ADV7481_OP_CSIB) { /* Enable 1-Lane MIPI Tx, enable pixel output and * route SD through Pixel port @@ -1373,54 +1810,57 @@ static int adv7481_csi_powerup(struct adv7481_state *state, ADV_REG_SETFIELD(1, IO_CTRL_PIX_OUT_EN) | ADV_REG_SETFIELD(1, IO_CTRL_SD_THRU_PIX_OUT) | ADV_REG_SETFIELD(0, IO_CTRL_CSI4_IN_SEL); - csi_map = state->i2c_csi_txb; + csi_map = state->i2c_csi_txb_addr; } else if (output == ADV7481_OP_TTL) { /* For now use TxA */ - csi_map = state->i2c_csi_txa; + csi_map = state->i2c_csi_txa_addr; } else { /* Default to TxA */ - csi_map = state->i2c_csi_txa; + csi_map = state->i2c_csi_txa_addr; } /* Enable Tx A/B CSI #-lane */ - ret = adv7481_wr_byte(state->client, + ret = adv7481_wr_byte(&state->i2c_client, state->i2c_io_addr, IO_REG_CSI_PIX_EN_SEL_ADDR, csi_sel); /* TXA MIPI lane settings for CSI */ /* CSI TxA: # Lane : Power Off */ val = ADV_REG_SETFIELD(1, CSI_CTRL_TX_PWRDN) | ADV_REG_SETFIELD(state->tx_lanes, CSI_CTRL_NUM_LANES); - ret |= adv7481_wr_byte(csi_map, CSI_REG_TX_CFG1_ADDR, val); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, + CSI_REG_TX_CFG1_ADDR, val); /* CSI TxA: Auto D-PHY Timing */ val |= ADV_REG_SETFIELD(1, CSI_CTRL_AUTO_PARAMS); - ret |= adv7481_wr_byte(csi_map, CSI_REG_TX_CFG1_ADDR, val); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, + CSI_REG_TX_CFG1_ADDR, val); /* DPHY and CSI Tx A */ - ret |= adv7481_wr_byte(csi_map, 0xdb, 0x10); - ret |= adv7481_wr_byte(csi_map, 0xd6, 0x07); - ret |= adv7481_wr_byte(csi_map, 0xc4, 0x0a); - ret |= adv7481_wr_byte(csi_map, 0x71, 0x33); - ret |= adv7481_wr_byte(csi_map, 0x72, 0x11); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xdb, 0x10); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xd6, 0x07); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xc4, 0x0a); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x71, 0x33); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x72, 0x11); /* CSI TxA: power up DPHY */ - ret |= adv7481_wr_byte(csi_map, 0xf0, 0x00); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xf0, 0x00); /* ADI Required Write */ - ret |= adv7481_wr_byte(csi_map, 0x31, 0x82); - ret |= adv7481_wr_byte(csi_map, 0x1e, 0x40); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x31, 0x82); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x1e, 0x40); /* adi Recommended power up sequence */ /* DPHY and CSI Tx A Power up Sequence */ /* CSI TxA: MIPI PLL EN */ - ret |= adv7481_wr_byte(csi_map, 0xda, 0x01); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xda, 0x01); msleep(200); /* CSI TxA: # MIPI Lane : Power ON */ val = ADV_REG_SETFIELD(0, CSI_CTRL_TX_PWRDN) | ADV_REG_SETFIELD(1, CSI_CTRL_AUTO_PARAMS) | ADV_REG_SETFIELD(state->tx_lanes, CSI_CTRL_NUM_LANES); - ret |= adv7481_wr_byte(csi_map, CSI_REG_TX_CFG1_ADDR, val); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, + CSI_REG_TX_CFG1_ADDR, val); msleep(100); /* ADI Required Write */ - ret |= adv7481_wr_byte(csi_map, 0xc1, 0x2b); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0xc1, 0x2b); msleep(100); /* ADI Required Write */ - ret |= adv7481_wr_byte(csi_map, 0x31, 0x80); + ret |= adv7481_wr_byte(&state->i2c_client, csi_map, 0x31, 0x80); pr_debug("Exit %s, ret: %d\n", __func__, ret); @@ -1476,42 +1916,30 @@ static int adv7481_g_input_status(struct v4l2_subdev *sd, u32 *status) { int ret = 0; struct adv7481_state *state = to_state(sd); - uint8_t val1 = 0; - uint8_t val2 = 0; + uint8_t val = 0; uint32_t count = 0; pr_debug("Enter %s\n", __func__); if (ADV7481_IP_HDMI == state->mode) { - /* - * Check Timing Lock IO Map Status3:0x71[0] && - * 0x71[1] && 0x71[7] - */ + /* Check Timing Lock */ do { - val1 = adv7481_rd_byte(state->client, - IO_HDMI_LVL_RAW_STATUS_3_ADDR); - val2 = adv7481_rd_byte(state->i2c_cp, - CP_REG_STDI_CH_ADDR); - - if (ADV_REG_GETFIELD(val1, IO_DE_REGEN_LCK_RAW) && - ADV_REG_GETFIELD(val1, IO_V_LOCKED_RAW) && - ADV_REG_GETFIELD(val1, IO_TMDSPLL_LCK_A_RAW) && - ADV_REG_GETFIELD(val2, CP_STDI_DVALID_CH1)) + if (adv7481_is_timing_locked(state)) break; count++; usleep_range(LOCK_MIN_SLEEP, LOCK_MAX_SLEEP); } while (count < LOCK_NUM_TRIES); if (count >= LOCK_NUM_TRIES) { - pr_err("%s(%d), HDMI DE regeneration block NOT Locked: 0x%x, 0x%x", - __func__, __LINE__, val1, val2); + pr_err("%s(%d), HDMI DE regeneration block NOT Locked\n", + __func__, __LINE__); *status |= V4L2_IN_ST_NO_SIGNAL; } } else { - val1 = adv7481_rd_byte(state->i2c_sdp, + val = adv7481_rd_byte(&state->i2c_client, state->i2c_sdp_addr, SDP_RO_MAIN_STATUS1_ADDR); - if (!ADV_REG_GETFIELD(val1, SDP_RO_MAIN_IN_LOCK)) { + if (!ADV_REG_GETFIELD(val, SDP_RO_MAIN_IN_LOCK)) { pr_err("%s(%d), SD Input NOT Locked: 0x%x\n", - __func__, __LINE__, val1); + __func__, __LINE__, val); *status |= V4L2_IN_ST_NO_SIGNAL; } } @@ -1539,6 +1967,7 @@ static const struct v4l2_subdev_video_ops adv7481_video_ops = { static const struct v4l2_subdev_core_ops adv7481_core_ops = { .s_power = adv7481_s_power, + .ioctl = adv7481_ioctl, }; static const struct v4l2_ctrl_ops adv7481_ctrl_ops = { @@ -1552,6 +1981,8 @@ static const struct v4l2_subdev_ops adv7481_ops = { static int adv7481_init_v4l2_controls(struct adv7481_state *state) { + int ret = 0; + v4l2_ctrl_handler_init(&state->ctrl_hdl, 4); v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7481_ctrl_ops, @@ -1565,59 +1996,218 @@ static int adv7481_init_v4l2_controls(struct adv7481_state *state) state->sd.ctrl_handler = &state->ctrl_hdl; if (state->ctrl_hdl.error) { - int err = state->ctrl_hdl.error; + ret = state->ctrl_hdl.error; v4l2_ctrl_handler_free(&state->ctrl_hdl); - return err; + } else { + v4l2_ctrl_handler_setup(&state->ctrl_hdl); } - v4l2_ctrl_handler_setup(&state->ctrl_hdl); - return 0; + pr_err("%s: Exit with ret: %d\n", __func__, ret); + return ret; } -static int adv7481_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl = { + .i2c_read = msm_camera_cci_i2c_read, + .i2c_read_seq = msm_camera_cci_i2c_read_seq, + .i2c_write = msm_camera_cci_i2c_write, + .i2c_write_table = msm_camera_cci_i2c_write_table, + .i2c_write_seq_table = msm_camera_cci_i2c_write_seq_table, + .i2c_write_table_w_microdelay = + msm_camera_cci_i2c_write_table_w_microdelay, + .i2c_util = msm_sensor_cci_i2c_util, + .i2c_poll = msm_camera_cci_i2c_poll, +}; + +static int adv7481_cci_init(struct adv7481_state *state) +{ + struct msm_camera_cci_client *cci_client = NULL; + int ret = 0; + + pr_err("%s: Enter\n", __func__); + + state->i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl; + state->i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR; + state->i2c_client.cci_client = kzalloc(sizeof( + struct msm_camera_cci_client), GFP_KERNEL); + cci_client = state->i2c_client.cci_client; + if (!cci_client) { + ret = -ENOMEM; + goto err_cci_init; + } + cci_client->cci_subdev = msm_cci_get_subdev(); + pr_debug("%s cci_subdev: %p\n", __func__, cci_client->cci_subdev); + cci_client->cci_i2c_master = state->cci_master; + cci_client->sid = state->i2c_slave_addr; + cci_client->retries = 3; + cci_client->id_map = 0; + cci_client->i2c_freq_mode = I2C_FAST_MODE; + ret = state->i2c_client.i2c_func_tbl->i2c_util( + &state->i2c_client, MSM_CCI_INIT); + if (ret < 0) + pr_err("%s - cci_init failed\n", __func__); + + pr_debug("%s i2c_client.client: %p\n", __func__, + state->i2c_client.client); + +err_cci_init: + return ret; +} + +static int adv7481_parse_dt(struct adv7481_state *state) +{ + struct device_node *np = state->dev->of_node; + unsigned int i; + int gpio_count = 0; + int flag_count = 0; + int label_count = 0; + int ret = 0; + + /* config CCI */ + ret = of_property_read_u32(np, "qcom,cci-master", + &state->cci_master); + if (ret < 0 || state->cci_master >= MASTER_MAX) { + pr_err("%s: failed ret %d\n", __func__, ret); + goto exit; + } + pr_debug("%s: cci_master: 0x%x\n", __func__, state->cci_master); + ret = of_property_read_u32(np, "qcom,slave-addr", + &state->i2c_slave_addr); + if (ret < 0) { + pr_err("%s: failed ret %d\n", __func__, ret); + goto exit; + } + pr_debug("%s: i2c_slave_addr: 0x%x\n", __func__, state->i2c_slave_addr); + state->i2c_io_addr = (uint8_t)state->i2c_slave_addr; + + ret = of_property_read_u32(np, "qcom,csi-slave-addr", + &state->i2c_csi_slave_addr); + if (ret < 0) { + pr_err("%s: failed ret %d\n", __func__, ret); + goto exit; + } + pr_debug("%s: i2c_csi_slave_addr: 0x%x\n", __func__, + state->i2c_csi_slave_addr); + ret = of_property_read_u32(np, "qcom,vpp-slave-addr", + &state->i2c_vpp_slave_addr); + if (ret < 0) { + pr_err("%s: failed ret %d\n", __func__, ret); + goto exit; + } + pr_debug("%s: i2c_vpp_slave_addr: 0x%x\n", __func__, + state->i2c_vpp_slave_addr); + + ret = adv7481_cci_init(state); + if (ret < 0) { + pr_err("%s: failed adv7481_cci_init ret %d\n", __func__, ret); + goto exit; + } + /* Configure GPIOs */ + gpio_count = of_gpio_count(np); + pr_debug("%s: of_gpio_count: 0x%x\n", __func__, gpio_count); + flag_count = of_property_count_u32_elems(np, "qcom,gpio-tbl-flags"); + pr_debug("%s: gpio-tbl-flags: 0x%x\n", __func__, flag_count); + label_count = of_property_count_strings(np, "qcom,gpio-tbl-label"); + pr_debug("%s: gpio-tbl-label: 0x%x\n", __func__, label_count); + if (gpio_count != ADV7481_GPIO_MAX || + flag_count != ADV7481_GPIO_MAX || + label_count != ADV7481_GPIO_MAX) { + ret = -EFAULT; + pr_err("%s: failed to configure GPIO ret -EFAULT\n", __func__); + goto exit; + } + for (i = 0; i < ADV7481_GPIO_MAX; i++) { + u32 tmp; + + state->gpio_array[i].gpio = of_get_gpio(np, i); + of_property_read_u32_index(np, "qcom,gpio-tbl-flags", i, &tmp); + state->gpio_array[i].flags = tmp; + of_property_read_string_index(np, "qcom,gpio-tbl-label", i, + &state->gpio_array[i].label); + pr_debug("%s: gpio_array[%d] = %d\n", __func__, i, + state->gpio_array[i].gpio); + } + pr_debug("%s: End read back gpio from dt...", __func__); + +exit: + return ret; +} + +static const struct of_device_id adv7481_id[] = { + { .compatible = "qcom,adv7481", }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, adv7481_id); + +static int adv7481_probe(struct platform_device *pdev) { struct adv7481_state *state; + const struct of_device_id *device_id; struct adv7481_platform_data *pdata = NULL; struct v4l2_subdev *sd; - struct v4l2_ctrl_handler *hdl; int ret; - pr_debug("Attempting to probe...\n"); - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - pr_err("%s %s Check i2c Functionality Fail\n", - __func__, client->name); - ret = -EIO; + device_id = of_match_device(adv7481_id, &pdev->dev); + if (!device_id) { + pr_err("%s: device_id is NULL\n", __func__); + ret = -ENODEV; goto err; } - v4l_info(client, "chip found @ 0x%02x (%s)\n", - client->addr, client->adapter->name); /* Create 7481 State */ - state = devm_kzalloc(&client->dev, - sizeof(struct adv7481_state), GFP_KERNEL); + state = devm_kzalloc(&pdev->dev, + sizeof(struct adv7481_state), GFP_KERNEL); if (state == NULL) { ret = -ENOMEM; - pr_err("Check Kzalloc Fail\n"); - goto err_mem; + goto err; } - state->client = client; + state->dev = &pdev->dev; + mutex_init(&state->mutex); - /* Get and Check Platform Data */ - pdata = (struct adv7481_platform_data *) client->dev.platform_data; - if (!pdata) { - ret = -ENOMEM; - pr_err("Getting Platform data failed\n"); - goto err_mem; + /* config VREG */ + ret = msm_camera_get_dt_vreg_data(pdev->dev.of_node, + &(state->cci_vreg), &(state->regulator_count)); + if (ret < 0) { + pr_err("%s:cci get_dt_vreg failed\n", __func__); + goto err_mem_free; } - /* Configure and Register V4L2 I2C Sub-device */ + ret = msm_camera_config_vreg(&pdev->dev, state->cci_vreg, + state->regulator_count, NULL, 0, + &state->cci_reg_ptr[0], 1); + if (ret < 0) { + pr_err("%s:cci config_vreg failed\n", __func__); + goto err_mem_free; + } + + ret = msm_camera_enable_vreg(&pdev->dev, state->cci_vreg, + state->regulator_count, NULL, 0, + &state->cci_reg_ptr[0], 1); + if (ret < 0) { + pr_err("%s:cci enable_vreg failed\n", __func__); + goto err_mem_free; + } + pr_debug("%s - VREG Initialized...\n", __func__); + + ret = adv7481_parse_dt(state); + pr_debug("%s - Done parsing dt...\n", __func__); + + /* Get and Check Platform Data */ + pdata = (struct adv7481_platform_data *) pdev->dev.platform_data; + if (!pdata) { + ret = -ENOMEM; + pr_err("%s(%d): Getting Platform data failed\n", + __func__, __LINE__); + goto err_mem_free; + } + + /* Configure and Register V4L2 Sub-device */ sd = &state->sd; - v4l2_i2c_subdev_init(sd, client, &adv7481_ops); + v4l2_subdev_init(sd, &adv7481_ops); + sd->owner = pdev->dev.driver->owner; + v4l2_set_subdevdata(sd, state); + strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name)); state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; state->sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS; @@ -1627,32 +2217,35 @@ static int adv7481_probe(struct i2c_client *client, ret = media_entity_init(&state->sd.entity, 1, &state->pad, 0); if (ret) { ret = -EIO; - pr_err("Media entity init failed\n"); + pr_err("%s(%d): Media entity init failed\n", + __func__, __LINE__); goto err_media_entity; } /* Initialize HW Config */ - ret = adv7481_hw_init(pdata, state); + ret = adv7481_hw_init(state); if (ret) { ret = -EIO; - pr_err("HW Initialisation Failed\n"); + pr_err("%s: HW Initialisation Failed\n", __func__); goto err_media_entity; } /* Register V4l2 Control Functions */ - hdl = &state->ctrl_hdl; - v4l2_ctrl_handler_init(hdl, 4); - adv7481_init_v4l2_controls(state); + ret = adv7481_init_v4l2_controls(state); + if (ret) { + pr_err("%s: V4L2 Controls Initialisation Failed %d\n", + __func__, ret); + } - /* Initials ADV7481 State Settings */ + /* Initial ADV7481 State Settings */ state->tx_auto_params = ADV7481_AUTO_PARAMS; - state->tx_lanes = ADV7481_MIPI_2LANE; /* Initialize SW Init Settings and I2C sub maps 7481 */ - ret = adv7481_dev_init(state, client); + ret = adv7481_dev_init(state); if (ret) { ret = -EIO; - pr_err("SW Initialisation Failed\n"); + pr_err("%s(%d): SW Initialisation Failed\n", + __func__, __LINE__); goto err_media_entity; } @@ -1672,7 +2265,7 @@ static int adv7481_probe(struct i2c_client *client, err_media_entity: media_entity_cleanup(&sd->entity); -err_mem: +err_mem_free: kfree(state); err: if (!ret) @@ -1680,50 +2273,39 @@ err: return ret; } -static int adv7481_remove(struct i2c_client *client) +static int adv7481_remove(struct platform_device *pdev) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct adv7481_state *state = to_state(sd); + struct adv7481_state *state; - msm_ba_unregister_subdev_node(sd); - v4l2_device_unregister_subdev(sd); - media_entity_cleanup(&sd->entity); + state = pdev->dev.platform_data; + msm_ba_unregister_subdev_node(&state->sd); + v4l2_device_unregister_subdev(&state->sd); + media_entity_cleanup(&state->sd.entity); v4l2_ctrl_handler_free(&state->ctrl_hdl); + adv7481_reset_irq(state); if (state->irq > 0) free_irq(state->irq, state); - i2c_unregister_device(state->i2c_csi_txa); - i2c_unregister_device(state->i2c_csi_txb); - i2c_unregister_device(state->i2c_hdmi); - i2c_unregister_device(state->i2c_edid); - i2c_unregister_device(state->i2c_cp); - i2c_unregister_device(state->i2c_sdp); - i2c_unregister_device(state->i2c_rep); + cancel_delayed_work(&state->irq_delayed_work); mutex_destroy(&state->mutex); kfree(state); return 0; } -static const struct i2c_device_id adv7481_id[] = { - { DRIVER_NAME, 0 }, - {}, -}; -MODULE_DEVICE_TABLE(i2c, adv7481_id); - - -static struct i2c_driver adv7481_driver = { +static struct platform_driver adv7481_driver = { .driver = { .owner = THIS_MODULE, .name = KBUILD_MODNAME, + .of_match_table = adv7481_id, }, .probe = adv7481_probe, .remove = adv7481_remove, - .id_table = adv7481_id, }; -module_i2c_driver(adv7481_driver); +module_driver(adv7481_driver, platform_driver_register, + platform_driver_unregister); MODULE_DESCRIPTION("ADI ADV7481 HDMI/MHL/SD video receiver"); diff --git a/drivers/media/i2c/adv7481_reg.h b/drivers/media/i2c/adv7481_reg.h index a4e14fa18e0a..a2dffa978b6d 100644 --- a/drivers/media/i2c/adv7481_reg.h +++ b/drivers/media/i2c/adv7481_reg.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,155 +19,233 @@ #define ADV_REG_GETFIELD(val, field) \ (((val) & (field##_BMSK)) >> (field##_SHFT)) +#define ADV_REG_RSTFIELD(val, field) \ + ((val) & ~((field##_BMSK) << (field##_SHFT))) + /* IO Map Registers */ -#define IO_REG_MAIN_RST_ADDR 0xFF -#define IO_REG_MAIN_RST_VALUE 0xFF +#define IO_REG_MAIN_RST_ADDR 0xFF +#define IO_REG_MAIN_RST_VALUE 0xFF -#define IO_REG_PWR_DOWN_CTRL_ADDR 0x00 -#define IO_CTRL_RX_EN_BMSK 0x0040 -#define IO_CTRL_RX_EN_SHFT 6 -#define IO_CTRL_RX_PWDN_BMSK 0x0020 -#define IO_CTRL_RX_PWDN_SHFT 5 -#define IO_CTRL_XTAL_PWDN_BMSK 0x0004 -#define IO_CTRL_XTAL_PWDN_SHFT 2 -#define IO_CTRL_CORE_PWDN_BMSK 0x0002 -#define IO_CTRL_CORE_PWDN_SHFT 1 -#define IO_CTRL_MASTER_PWDN_BMSK 0x0001 -#define IO_CTRL_MASTER_PWDN_SHFT 0 +#define IO_REG_PWR_DOWN_CTRL_ADDR 0x00 +#define IO_CTRL_RX_EN_BMSK 0x0040 +#define IO_CTRL_RX_EN_SHFT 6 +#define IO_CTRL_RX_PWDN_BMSK 0x0020 +#define IO_CTRL_RX_PWDN_SHFT 5 +#define IO_CTRL_XTAL_PWDN_BMSK 0x0004 +#define IO_CTRL_XTAL_PWDN_SHFT 2 +#define IO_CTRL_CORE_PWDN_BMSK 0x0002 +#define IO_CTRL_CORE_PWDN_SHFT 1 +#define IO_CTRL_MASTER_PWDN_BMSK 0x0001 +#define IO_CTRL_MASTER_PWDN_SHFT 0 -#define IO_REG_PWR_DN2_XTAL_HIGH_ADDR 0x01 -#define IO_CTRL_CEC_WAKE_UP_PWRDN2B_BMSK 0x0080 -#define IO_CTRL_CEC_WAKE_UP_PWRDN2B_SHFT 7 +#define IO_REG_PWR_DN2_XTAL_HIGH_ADDR 0x01 +#define IO_CTRL_CEC_WAKE_UP_PWRDN2B_BMSK 0x0080 +#define IO_CTRL_CEC_WAKE_UP_PWRDN2B_SHFT 7 #define IO_CTRL_CEC_WAKE_UP_PWRDNB_BMSK 0x0040 #define IO_CTRL_CEC_WAKE_UP_PWRDNB_SHFT 6 -#define IO_PROG_XTAL_FREQ_HIGH_BMSK 0x003F -#define IO_PROG_XTAL_FREQ_HIGH_SHFT 0 +#define IO_PROG_XTAL_FREQ_HIGH_BMSK 0x003F +#define IO_PROG_XTAL_FREQ_HIGH_SHFT 0 -#define IO_REG_XTAL_FREQ_LOW_ADDR 0x02 -#define IO_PROG_XTAL_FREQ_LOW_BMSK 0x00FF -#define IO_PROG_XTAL_FREQ_LOW_SHFT 0 +#define IO_REG_XTAL_FREQ_LOW_ADDR 0x02 +#define IO_PROG_XTAL_FREQ_LOW_BMSK 0x00FF +#define IO_PROG_XTAL_FREQ_LOW_SHFT 0 -#define IO_REG_CP_VID_STD_ADDR 0x05 +#define IO_REG_CP_VID_STD_ADDR 0x05 -#define IO_REG_CSI_PIX_EN_SEL_ADDR 0x10 -#define IO_CTRL_CSI4_EN_BMSK 0x0080 -#define IO_CTRL_CSI4_EN_SHFT 7 -#define IO_CTRL_CSI1_EN_BMSK 0x0040 -#define IO_CTRL_CSI1_EN_SHFT 6 +#define IO_REG_CSI_PIX_EN_SEL_ADDR 0x10 +#define IO_CTRL_CSI4_EN_BMSK 0x0080 +#define IO_CTRL_CSI4_EN_SHFT 7 +#define IO_CTRL_CSI1_EN_BMSK 0x0040 +#define IO_CTRL_CSI1_EN_SHFT 6 #define IO_CTRL_PIX_OUT_EN_BMSK 0x0020 #define IO_CTRL_PIX_OUT_EN_SHFT 5 -#define IO_CTRL_SD_THRU_PIX_OUT_BMSK 0x0010 -#define IO_CTRL_SD_THRU_PIX_OUT_SHFT 4 -#define IO_CTRL_CSI4_IN_SEL_BMSK 0x000C -#define IO_CTRL_CSI4_IN_SEL_SHFT 2 +#define IO_CTRL_SD_THRU_PIX_OUT_BMSK 0x0010 +#define IO_CTRL_SD_THRU_PIX_OUT_SHFT 4 +#define IO_CTRL_CSI4_IN_SEL_BMSK 0x000C +#define IO_CTRL_CSI4_IN_SEL_SHFT 2 -#define IO_PAD_CTRLS_ADDR 0x0E +#define IO_PAD_CTRLS_ADDR 0x0E +#define IO_PAD_FILTER_CTRLS_ADDR 0x0F -#define IO_REG_I2C_CFG_ADDR 0xF2 +#define IO_REG_I2C_CFG_ADDR 0xF2 #define IO_REG_I2C_AUTOINC_EN_REG_VALUE 0x01 -#define IO_CTRL_MASTER_PWDN_REG_VALUE 0x01 - -#define IO_HDMI_LVL_RAW_STATUS_3_ADDR 0x71 -#define IO_TMDSPLL_LCK_A_RAW_BMSK 0x0080 -#define IO_TMDSPLL_LCK_A_RAW_SHFT 7 -#define IO_CABLE_DET_A_RAW_BMSK 0x0040 -#define IO_CABLE_DET_A_RAW_SHFT 6 -#define IO_V_LOCKED_RAW_BMSK 0x0002 -#define IO_V_LOCKED_RAW_SHFT 1 -#define IO_DE_REGEN_LCK_RAW_BMSK 0x0001 -#define IO_DE_REGEN_LCK_RAW_SHFT 0 +#define IO_CTRL_MASTER_PWDN_REG_VALUE 0x01 /* Interrupts */ -#define IO_HDMI_LVL_INT_STATUS_3_ADDR 0x72 -#define IO_CABLE_DET_A_ST_BMSK 0x0040 -#define IO_CABLE_DET_A_ST_SHFT 6 +#define IO_HDMI_LVL_INT_CLEAR_1_ADDR 0x69 -#define IO_HDMI_LVL_INT_CLEAR_3_ADDR 0x73 +#define IO_HDMI_LVL_INT_MASKB_1_ADDR 0x6B +#define IO_AVI_INFO_MB1_BMSK 0x0001 +#define IO_AVI_INFO_MB1_SHFT 0 + +#define IO_HDMI_LVL_INT_CLEAR_2_ADDR 0x6E + +#define IO_HDMI_LVL_RAW_STATUS_3_ADDR 0x71 +#define IO_TMDSPLL_LCK_A_RAW_BMSK 0x0080 +#define IO_TMDSPLL_LCK_A_RAW_SHFT 7 +#define IO_CABLE_DET_A_RAW_BMSK 0x0040 +#define IO_CABLE_DET_A_RAW_SHFT 6 +#define IO_V_LOCKED_RAW_BMSK 0x0002 +#define IO_V_LOCKED_RAW_SHFT 1 +#define IO_DE_REGEN_LCK_RAW_BMSK 0x0001 +#define IO_DE_REGEN_LCK_RAW_SHFT 0 + +#define IO_HDMI_LVL_INT_STATUS_3_ADDR 0x72 +#define IO_CABLE_DET_A_ST_BMSK 0x0040 +#define IO_CABLE_DET_A_ST_SHFT 6 +#define IO_V_LOCKED_ST_BMSK 0x0002 +#define IO_V_LOCKED_ST_SHFT 1 +#define IO_DE_REGEN_LCK_ST_BMSK 0x0001 +#define IO_DE_REGEN_LCK_ST_SHFT 0 + +#define IO_HDMI_LVL_INT_CLEAR_3_ADDR 0x73 #define IO_CABLE_DET_A_CLR_BMSK 0x0040 #define IO_CABLE_DET_A_CLR_SHFT 6 -#define IO_HDMI_LVL_INT2_MASKB_3_ADDR 0x74 +#define IO_HDMI_LVL_INT2_MASKB_3_ADDR 0x74 #define IO_CABLE_DET_A_MB2_BMSK 0x0040 #define IO_CABLE_DET_A_MB2_SHFT 6 -#define IO_HDMI_LVL_INT_MASKB_3_ADDR 0x75 +#define IO_HDMI_LVL_INT_MASKB_3_ADDR 0x75 #define IO_CABLE_DET_A_MB1_BMSK 0x0040 #define IO_CABLE_DET_A_MB1_SHFT 6 +#define IO_V_LOCKED_MB1_BMSK 0x0002 +#define IO_V_LOCKED_MB1_SHFT 1 +#define IO_DE_REGEN_LCK_MB1_BMSK 0x0001 +#define IO_DE_REGEN_LCK_MB1_SHFT 0 -#define IO_REG_PAD_CTRL_1_ADDR 0x1D -#define IO_PDN_INT1_BMSK 0x0080 -#define IO_PDN_INT1_SHFT 7 -#define IO_PDN_INT2_BMSK 0x0040 -#define IO_PDN_INT2_SHFT 6 -#define IO_PDN_INT3_BMSK 0x0020 -#define IO_PDN_INT3_SHFT 5 +#define IO_HDMI_EDG_RAW_STATUS_1_ADDR 0x80 +#define IO_NEW_AVI_INFO_RAW_BMSK 0x0001 +#define IO_NEW_AVI_INFO_RAW_SHFT 0 + +#define IO_HDMI_EDG_INT_STATUS_1_ADDR 0x81 +#define IO_NEW_AVI_INFO_ST_BMSK 0x0001 +#define IO_NEW_AVI_INFO_ST_SHFT 0 + +#define IO_HDMI_EDG_INT_CLEAR_1_ADDR 0x82 +#define IO_NEW_AVI_INFO_CLR_BMSK 0x0001 +#define IO_NEW_AVI_INFO_CLR_SHFT 0 + +#define IO_HDMI_EDG_INT2_MASKB_1_ADDR 0x83 +#define IO_NEW_AVI_INFO_MB2_BMSK 0x0001 +#define IO_NEW_AVI_INFO_MB2_SHFT 0 + +#define IO_HDMI_EDG_INT_MASKB_1_ADDR 0x84 +#define IO_NEW_AVI_INFO_MB1_BMSK 0x0001 +#define IO_NEW_AVI_INFO_MB1_SHFT 0 + +#define IO_HDMI_EDG_INT_CLEAR_2_ADDR 0x87 +#define IO_HDMI_EDG_INT_CLEAR_3_ADDR 0x8C + +#define IO_REG_PAD_CTRL_1_ADDR 0x1D +#define IO_PDN_INT1_BMSK 0x0080 +#define IO_PDN_INT1_SHFT 7 +#define IO_PDN_INT2_BMSK 0x0040 +#define IO_PDN_INT2_SHFT 6 +#define IO_PDN_INT3_BMSK 0x0020 +#define IO_PDN_INT3_SHFT 5 #define IO_INV_LLC_BMSK 0x0010 #define IO_INV_LLC_SHFT 4 -#define IO_DRV_LLC_PAD_BMSK 0x000C -#define IO_DRV_LLC_PAD_SHFT 2 +#define IO_DRV_LLC_PAD_BMSK 0x000C +#define IO_DRV_LLC_PAD_SHFT 2 -#define IO_REG_INT_RAW_STATUS_ADDR 0x3F +#define IO_REG_INT_RAW_STATUS_ADDR 0x3F +#define IO_INT_CEC_ST_BMSK 0x0010 +#define IO_INT_CEC_ST_SHFT 4 +#define IO_INT_HDMI_ST_BMSK 0x0008 +#define IO_INT_HDMI_ST_SHFT 3 +#define IO_INTRQ3_RAW_BMSK 0x0004 +#define IO_INTRQ3_RAW_SHFT 2 +#define IO_INTRQ2_RAW_BMSK 0x0002 +#define IO_INTRQ2_RAW_SHFT 1 +#define IO_INTRQ1_RAW_BMSK 0x0001 +#define IO_INTRQ1_RAW_SHFT 0 -#define IO_REG_INT1_CONF_ADDR 0x40 -#define IO_INTRQ_DUR_SEL_BMSK 0x00C0 -#define IO_INTRQ_DUR_SEL_SHFT 6 -#define IO_INTRQ_OP_SEL_BMSK 0x0003 -#define IO_INTRQ_OP_SEL_SHFT 0 +#define IO_REG_INT1_CONF_ADDR 0x40 +#define IO_INTRQ_DUR_SEL_BMSK 0x00C0 +#define IO_INTRQ_DUR_SEL_SHFT 6 +#define IO_INTRQ_OP_SEL_BMSK 0x0003 +#define IO_INTRQ_OP_SEL_SHFT 0 -#define IO_REG_INT2_CONF_ADDR 0x41 -#define IO_INTRQ2_DUR_SEL_BMSK 0x00C0 -#define IO_INTRQ2_DUR_SEL_SHFT 6 +#define IO_REG_INT2_CONF_ADDR 0x41 +#define IO_INTRQ2_DUR_SEL_BMSK 0x00C0 +#define IO_INTRQ2_DUR_SEL_SHFT 6 #define IO_CP_LOCK_UNLOCK_EDGE_SEL_BMSK 0x0020 #define IO_CP_LOCK_UNLOCK_EDGE_SEL_SHFT 5 -#define IO_EN_UMASK_RAW_INTRQ2_BMSK 0x0008 -#define IO_EN_UMASK_RAW_INTRQ2_SHFT 3 +#define IO_EN_UMASK_RAW_INTRQ2_BMSK 0x0008 +#define IO_EN_UMASK_RAW_INTRQ2_SHFT 3 #define IO_INT2_EN_BMSK 0x0004 #define IO_INT2_EN_SHFT 2 -#define IO_INTRQ2_OP_SEL_BMSK 0x0003 -#define IO_INTRQ2_OP_SEL_SHFT 0 +#define IO_INTRQ2_OP_SEL_BMSK 0x0003 +#define IO_INTRQ2_OP_SEL_SHFT 0 #define IO_REG_DATAPATH_RAW_STATUS_ADDR 0x43 -#define IO_REG_DATAPATH_INT_STATUS_ADDR 0x44 -#define IO_REG_DATAPATH_INT_CLEAR_ADDR 0x45 +#define IO_CP_LOCK_CP_RAW_BMSK 0x0080 +#define IO_CP_LOCK_CP_RAW_SHFT 7 +#define IO_CP_UNLOCK_CP_RAW_BMSK 0x0040 +#define IO_CP_UNLOCK_CP_RAW_SHFT 6 +#define IO_VMUTE_REQUEST_HDMI_RAW_BMSK 0x0020 +#define IO_VMUTE_REQUEST_HDMI_RAW_SHFT 5 +#define IO_MPU_STIM_INTRQ_RAW_BMSK 0x0002 +#define IO_MPU_STIM_INTRQ_RAW_SHFT 1 +#define IO_INT_SD_RAW_BMSK 0x0001 +#define IO_INT_SD_RAW_SHFT 0 -#define IO_REG_DATAPATH_INT_MASKB_ADDR 0x47 -#define IO_CP_LOCK_CP_MB1_BMSK 0x0080 -#define IO_CP_LOCK_CP_MB1_SHFT 7 -#define IO_CP_UNLOCK_CP_MB1_BMSK 0x0040 -#define IO_CP_UNLOCK_CP_MB1_SHFT 6 -#define IO_VMUTE_REQUEST_HDMI_MB1_BMSK 0x0020 -#define IO_VMUTE_REQUEST_HDMI_MB1_SHFT 5 -#define IO_MPU_STIM_INTRQ_MB1_BMSK 0x0002 -#define IO_MPU_STIM_INTRQ_MB1_SHFT 1 -#define IO_INT_SD_MB1_BMSK 0x0001 -#define IO_INT_SD_MB1_SHFT 0 +#define IO_REG_DATAPATH_INT_STATUS_ADDR 0x44 +#define IO_CP_LOCK_CP_ST_BMSK 0x0080 +#define IO_CP_LOCK_CP_ST_SHFT 7 +#define IO_CP_UNLOCK_CP_ST_BMSK 0x0040 +#define IO_CP_UNLOCK_CP_ST_SHFT 6 +#define IO_VMUTE_REQUEST_HDMI_ST_BMSK 0x0020 +#define IO_VMUTE_REQUEST_HDMI_ST_SHFT 5 +#define IO_MPU_STIM_INTRQ_ST_BMSK 0x0002 +#define IO_MPU_STIM_INTRQ_ST_SHFT 1 +#define IO_INT_SD_ST_BMSK 0x0001 +#define IO_INT_SD_ST_SHFT 0 + +#define IO_REG_DATAPATH_INT_CLEAR_ADDR 0x45 + +#define IO_REG_DATAPATH_INT_MASKB_ADDR 0x47 +#define IO_CP_LOCK_CP_MB1_BMSK 0x0080 +#define IO_CP_LOCK_CP_MB1_SHFT 7 +#define IO_CP_UNLOCK_CP_MB1_BMSK 0x0040 +#define IO_CP_UNLOCK_CP_MB1_SHFT 6 +#define IO_VMUTE_REQUEST_HDMI_MB1_BMSK 0x0020 +#define IO_VMUTE_REQUEST_HDMI_MB1_SHFT 5 +#define IO_MPU_STIM_INTRQ_MB1_BMSK 0x0002 +#define IO_MPU_STIM_INTRQ_MB1_SHFT 1 +#define IO_INT_SD_MB1_BMSK 0x0001 +#define IO_INT_SD_MB1_SHFT 0 + +#define IO_REG_CHIP_REV_ID_1_ADDR 0xDF +#define IO_REG_CHIP_REV_ID_2_ADDR 0xE0 /* Offsets */ -#define IO_REG_DPLL_ADDR 0xF3 -#define IO_REG_CP_ADDR 0xF4 -#define IO_REG_HDMI_ADDR 0xF5 -#define IO_REG_EDID_ADDR 0xF6 -#define IO_REG_HDMI_REP_ADDR 0xF7 -#define IO_REG_HDMI_INF_ADDR 0xF8 -#define IO_REG_CBUS_ADDR 0xF9 -#define IO_REG_CEC_ADDR 0xFA -#define IO_REG_SDP_ADDR 0xFB -#define IO_REG_CSI_TXB_ADDR 0xFC -#define IO_REG_CSI_TXA_ADDR 0xFD +#define IO_REG_DPLL_ADDR 0xF3 +#define IO_REG_CP_ADDR 0xF4 +#define IO_REG_HDMI_ADDR 0xF5 +#define IO_REG_EDID_ADDR 0xF6 +#define IO_REG_HDMI_REP_ADDR 0xF7 +#define IO_REG_HDMI_INF_ADDR 0xF8 +#define IO_REG_CBUS_ADDR 0xF9 +#define IO_REG_CEC_ADDR 0xFA +#define IO_REG_SDP_ADDR 0xFB +#define IO_REG_CSI_TXB_ADDR 0xFC +#define IO_REG_CSI_TXA_ADDR 0xFD /* Sub Address Map Locations */ -#define IO_REG_DPLL_SADDR 0x4C -#define IO_REG_CP_SADDR 0x44 -#define IO_REG_HDMI_SADDR 0x74 -#define IO_REG_EDID_SADDR 0x78 -#define IO_REG_HDMI_REP_SADDR 0x64 -#define IO_REG_HDMI_INF_SADDR 0x62 -#define IO_REG_CBUS_SADDR 0xF0 -#define IO_REG_CEC_SADDR 0x82 -#define IO_REG_SDP_SADDR 0xF2 -#define IO_REG_CSI_TXB_SADDR 0x90 -#define IO_REG_CSI_TXA_SADDR 0x94 +#define IO_REG_DPLL_SADDR 0x4C +#define IO_REG_CP_SADDR 0x44 +#define IO_REG_HDMI_SADDR 0x74 +#define IO_REG_EDID_SADDR 0x78 +#define IO_REG_HDMI_REP_SADDR 0x64 +#define IO_REG_HDMI_INF_SADDR 0x62 +#define IO_REG_CBUS_SADDR 0xF0 +#define IO_REG_CEC_SADDR 0x82 +#define IO_REG_SDP_SADDR 0xF2 +#define IO_REG_CSI_TXB_SADDR 0x90 +#define IO_REG_CSI_TXA_SADDR 0x94 /* HDMI Map Registers */ #define HDMI_REG_HDMI_PARAM4_ADDR 0x04 @@ -179,10 +257,10 @@ #define HDMI_REG_AUDIO_PLL_LOCKED_SHFT 0 #define HDMI_REG_HDMI_PARAM5_ADDR 0x05 -#define HDMI_REG_HDMI_MODE_BMSK 0x0080 +#define HDMI_REG_HDMI_MODE_BMSK 0x0080 #define HDMI_REG_TMDS_FREQ_0_SHFT 7 -#define HDMI_REG_HDMI_CONT_ENCRYPT_BMSK 0x0040 -#define HDMI_REG_HDMI_CONT_ENCRYPT_SHFT 6 +#define HDMI_REG_HDMI_CONT_ENCRYPT_BMSK 0x0040 +#define HDMI_REG_HDMI_CONT_ENCRYPT_SHFT 6 #define HDMI_REG_DVI_HSYNC_POLARITY_BMSK 0x0020 #define HDMI_REG_DVI_HSYNC_POLARITY_SHFT 5 #define HDMI_REG_DVI_VSYNC_POLARITY_BMSK 0x0010 @@ -233,13 +311,13 @@ #define HDMI_REG_FIELD0_TOT_HEIGHT_2_BMSK 0x00FF #define HDMI_REG_FIELD0_TOT_HEIGHT_2_SHFT 0 -#define HDMI_REG_DIS_CABLE_DET_RST_ADDR 0x48 +#define HDMI_REG_DIS_CABLE_DET_RST_ADDR 0x48 #define HDMI_DIS_CABLE_DET_RST_BMSK 0x0040 #define HDMI_DIS_CABLE_DET_RST_SHFT 6 -#define HDMI_REG_TMDS_FREQ_ADDR 0x51 -#define HDMI_REG_TMDS_FREQ_BMSK 0x00FF -#define HDMI_REG_TMDS_FREQ_SHFT 0 +#define HDMI_REG_TMDS_FREQ_ADDR 0x51 +#define HDMI_REG_TMDS_FREQ_BMSK 0x00FF +#define HDMI_REG_TMDS_FREQ_SHFT 0 #define HDMI_REG_TMDS_FREQ_FRAC_ADDR 0x52 #define HDMI_REG_TMDS_FREQ_0_BMSK 0x0080 @@ -247,7 +325,7 @@ #define HDMI_REG_TMDS_FREQ_FRAC_BMSK 0x007F #define HDMI_REG_TMDS_FREQ_FRAC_SHFT 0 -#define HDMI_REG_RST_CTRLS_ADDR 0x5A +#define HDMI_REG_RST_CTRLS_ADDR 0x5A #define HDMI_HDCP_REPT_EDID_RST_BMSK 0x0008 #define HDMI_HDCP_REPT_EDID_RST_SHFT 3 @@ -261,19 +339,55 @@ #define HDMI_MAN_EDID_A_ENABLE_SHFT 0 #define HDMI_REG_RO_EDID_DEBUG_2_ADDR 0x76 -#define HDMI_EDID_A_ENABLE_BMSK 0x0001 -#define HDMI_EDID_A_ENABLE_SHFT 0 +#define HDMI_EDID_A_ENABLE_BMSK 0x0001 +#define HDMI_EDID_A_ENABLE_SHFT 0 + +/* CEC Map Registers */ +#define CEC_REG_LOG_ADDR_MASK_ADDR 0x27 +#define CEC_REG_LOG_ADDR_MASK2_BMSK 0x0040 +#define CEC_REG_LOG_ADDR_MASK2_SHFT 6 +#define CEC_REG_LOG_ADDR_MASK1_BMSK 0x0020 +#define CEC_REG_LOG_ADDR_MASK1_SHFT 5 +#define CEC_REG_LOG_ADDR_MASK0_BMSK 0x0010 +#define CEC_REG_LOG_ADDR_MASK0_SHFT 4 +#define CEC_REG_ERROR_REPORT_MODE_BMSK 0x0008 +#define CEC_REG_ERROR_REPORT_MODE_SHFT 3 +#define CEC_REG_ERROR_REPORT_DET_BMSK 0x0004 +#define CEC_REG_ERROR_REPORT_DET_SHFT 2 +#define CEC_REG_FORCE_NACK_BMSK 0x0002 +#define CEC_REG_FORCE_NACK_SHFT 1 +#define CEC_REG_FORCE_IGNORE_BMSK 0x0001 +#define CEC_REG_FORCE_IGNORE_SHFT 0 + +#define CEC_REG_LOGICAL_ADDRESS0_1_ADDR 0x28 +#define CEC_REG_LOGICAL_ADDRESS1_BMSK 0x00F0 +#define CEC_REG_LOGICAL_ADDRESS1_SHFT 4 +#define CEC_REG_LOGICAL_ADDRESS0_BMSK 0x000F +#define CEC_REG_LOGICAL_ADDRESS0_SHFT 0 + +#define CEC_REG_LOGICAL_ADDRESS2_ADDR 0x29 +#define CEC_REG_LOGICAL_ADDRESS2_BMSK 0x000F +#define CEC_REG_LOGICAL_ADDRESS2_SHFT 0 + +#define CEC_REG_CEC_POWER_UP_ADDR 0x2A +#define CEC_REG_CEC_POWER_UP_BMSK 0x0001 +#define CEC_REG_CEC_POWER_UP_SHFT 0 + +#define CEC_REG_CLR_RX_RDY_SFT_RST_ADDR 0x2C +#define CEC_REG_CEC_SOFT_RESET_BMSK 0x0001 +#define CEC_REG_CEC_SOFT_RESET_SHFT 0 + /* CP Map Registers */ -#define CP_REG_CONTRAST 0x3A -#define CP_REG_SATURATION 0x3B -#define CP_REG_BRIGHTNESS 0x3C -#define CP_REG_HUE 0x3D -#define CP_REG_VID_ADJ 0x3E -#define CP_CTR_VID_ADJ_EN 0x80 +#define CP_REG_CONTRAST 0x3A +#define CP_REG_SATURATION 0x3B +#define CP_REG_BRIGHTNESS 0x3C +#define CP_REG_HUE 0x3D +#define CP_REG_VID_ADJ 0x3E +#define CP_CTR_VID_ADJ_EN 0x80 #define CP_REG_STDI_CH_ADDR 0xB1 -#define CP_STDI_DVALID_CH1_BMSK 0x0080 -#define CP_STDI_DVALID_CH1_SHFT 7 +#define CP_STDI_DVALID_CH1_BMSK 0x0080 +#define CP_STDI_DVALID_CH1_SHFT 7 /* SDP R/O Main Map Registers */ #define SDP_RO_MAIN_STATUS1_ADDR 0x10 @@ -298,50 +412,50 @@ #define CSI_CTRL_TX_PWRDN_SHFT 7 #define CSI_CTRL_AUTO_PARAMS_BMSK 0x0020 #define CSI_CTRL_AUTO_PARAMS_SHFT 5 -#define CSI_CTRL_NUM_LANES_BMSK 0x0007 -#define CSI_CTRL_NUM_LANES_SHFT 0 +#define CSI_CTRL_NUM_LANES_BMSK 0x0007 +#define CSI_CTRL_NUM_LANES_SHFT 0 #define CSI_REG_TX_DPHY_PWDN_ADDR 0xF0 -#define CSI_CTRL_DPHY_PWDN_BMSK 0x0001 -#define CSI_CTRL_DPHY_PWDN_SHFT 0 +#define CSI_CTRL_DPHY_PWDN_BMSK 0x0001 +#define CSI_CTRL_DPHY_PWDN_SHFT 0 enum adv7481_adresult { - AD_NTSM_M_J = 0x0, - AD_NTSC_4_43 = 0x1, - AD_PAL_M = 0x2, - AD_PAL_60 = 0x3, - AD_PAL_B_G = 0x4, - AD_SECAM = 0x5, - AD_PAL_COMB_N = 0x6, - AD_SECAM_525 = 0x7, + AD_NTSM_M_J = 0x0, + AD_NTSC_4_43 = 0x1, + AD_PAL_M = 0x2, + AD_PAL_60 = 0x3, + AD_PAL_B_G = 0x4, + AD_SECAM = 0x5, + AD_PAL_COMB_N = 0x6, + AD_SECAM_525 = 0x7, }; enum adv7481_color_depth { - CD_8BIT = 0x0, - CD_10BIT = 0x1, - CD_12BIT = 0x2, - CD_16BIT = 0x3, + CD_8BIT = 0x0, + CD_10BIT = 0x1, + CD_12BIT = 0x2, + CD_16BIT = 0x3, }; enum adv7481_intrq_dur_sel { - AD_4_XTAL_PER = 0x0, - AD_16_XTAL_PER = 0x1, - AD_64_XTAL_PER = 0x2, - AD_ACTIVE_UNTIL_CLR = 0x3, + AD_4_XTAL_PER = 0x0, + AD_16_XTAL_PER = 0x1, + AD_64_XTAL_PER = 0x2, + AD_ACTIVE_UNTIL_CLR = 0x3, }; enum adv7481_intrq_op_sel { - AD_OP_OPEN_DRAIN = 0x0, - AD_OP_DRIVE_LOW = 0x1, - AD_OP_DRIVE_HIGH = 0x2, - AD_OP_DISABLED = 0x3, + AD_OP_OPEN_DRAIN = 0x0, + AD_OP_DRIVE_LOW = 0x1, + AD_OP_DRIVE_HIGH = 0x2, + AD_OP_DISABLED = 0x3, }; enum adv7481_drv_llc_pad { - AD_LLC_PAD_NOT_USED = 0x0, - AD_MIN_DRIVE_STRNGTH = 0x1, - AD_MID_DRIVE_STRNGTH = 0x2, - AD_MAX_DRIVE_STRNGTH = 0x3, + AD_LLC_PAD_NOT_USED = 0x0, + AD_MIN_DRIVE_STRNGTH = 0x1, + AD_MID_DRIVE_STRNGTH = 0x2, + AD_MAX_DRIVE_STRNGTH = 0x3, }; #endif