Loading Documentation/devicetree/bindings/arm/msm/adv7481.txt +9 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,9 @@ 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. - gpios: The GPIOs required to be configured for the driver. It should be in the order I2C data line, i2c clock line, reset line, interrupt 1, interrupt 2 and interrupt 3. Example: Loading @@ -17,4 +20,10 @@ Example: compatible = "qcom,adv7481"; qcom,cci-master = <0>; qcom,slave-addr = <0x70>; gpios = <&tlmm 17 0>, /* I2C SDA */ <&tlmm 18 0>, /* I2C SCL */ <&pm8994_gpios 4 0>, /* RST */ <&pm8994_gpios 5 0>, /* INT1 */ <&pm8994_gpios 6 0>, /* INT2 */ <&pm8994_gpios 7 0>; /* INT3 */ }; arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi +13 −8 Original line number Diff line number Diff line Loading @@ -698,14 +698,11 @@ }; &pm8994_gpios { gpio@c600 { /* GPIO 7 - NFC DWL REQ */ qcom,mode = <1>; qcom,output-type = <0>; qcom,pull = <5>; gpio@c600 { /* GPIO 7 - adv7481 INT3 */ qcom,mode = <0>; qcom,pull = <0>; qcom,vin-sel = <2>; qcom,out-strength = <3>; qcom,src-sel = <0>; qcom,master-en = <1>; status = "okay"; }; Loading Loading @@ -756,7 +753,15 @@ status = "okay"; }; gpio@c300 { /* GPIO 4 */ gpio@c300 { /* GPIO 4 - adv7481 RST */ qcom,mode = <1>; qcom,pull = <0>; qcom,vin-sel = <2>; qcom,src-sel = <0>; status = "okay"; }; gpio@c400 { /* GPIO 5 - adv7481 INT1 */ qcom,mode = <0>; qcom,pull = <0>; qcom,vin-sel = <2>; Loading @@ -764,7 +769,7 @@ status = "okay"; }; gpio@c400 { /* GPIO 5 */ gpio@c500 { /* GPIO 6 - adv7481 INT2*/ qcom,mode = <0>; qcom,pull = <0>; qcom,vin-sel = <2>; Loading drivers/media/i2c/adv7481.c +34 −99 Original line number Diff line number Diff line Loading @@ -77,22 +77,12 @@ enum adv7481_gpio_t { }; 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; Loading Loading @@ -589,7 +579,7 @@ static int adv7481_dev_init(struct adv7481_state *state) 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); udelay(I2C_SW_RST_DELAY); chip_rev_id = adv7481_rd_word(&state->i2c_client, state->i2c_io_addr, IO_REG_CHIP_REV_ID_1_ADDR); Loading Loading @@ -678,12 +668,10 @@ static int adv7481_hw_init(struct adv7481_state *state) 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); udelay(GPIO_HW_RST_DELAY_LOW); 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); udelay(GPIO_HW_RST_DELAY_HI); if (ret) { pr_err("%s: Set GPIO Fail %d\n", __func__, ret); goto err_exit; Loading Loading @@ -2036,6 +2024,10 @@ static int adv7481_cci_init(struct adv7481_state *state) } cci_client->cci_subdev = msm_cci_get_subdev(); pr_debug("%s cci_subdev: %p\n", __func__, cci_client->cci_subdev); if (!cci_client->cci_subdev) { ret = -EPROBE_DEFER; goto err_cci_init; } cci_client->cci_i2c_master = state->cci_master; cci_client->sid = state->i2c_slave_addr; cci_client->retries = 3; Loading @@ -2056,77 +2048,47 @@ err_cci_init: static int adv7481_parse_dt(struct adv7481_state *state) { struct device_node *np = state->dev->of_node; unsigned int i; uint32_t i = 0; 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); pr_err("%s: failed to read cci master . 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); pr_err("%s: failed to read slave-addr. 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) { if (gpio_count != ADV7481_GPIO_MAX) { ret = -EFAULT; pr_err("%s: failed to configure GPIO ret -EFAULT\n", __func__); pr_err("%s: dt gpio count %d doesn't match required. ret %d\n", __func__, gpio_count, ret); 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); state->gpio_array[i].gpio = of_get_gpio_flags(np, i, (enum of_gpio_flags *)&state->gpio_array[i].flags); if (!gpio_is_valid(state->gpio_array[i].gpio)) { pr_err("invalid gpio setting for index %d\n", i); ret = -EFAULT; goto exit; } pr_debug("%s: gpio_array[%d] = %d flag = %ld\n", __func__, i, state->gpio_array[i].gpio, state->gpio_array[i].flags); } pr_debug("%s: End read back gpio from dt...", __func__); exit: return ret; Loading @@ -2142,7 +2104,6 @@ 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; int ret; Loading @@ -2160,44 +2121,19 @@ static int adv7481_probe(struct platform_device *pdev) ret = -ENOMEM; goto err; } platform_set_drvdata(pdev, state); state->dev = &pdev->dev; mutex_init(&state->mutex); /* 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; } ret = msm_camera_config_vreg(&pdev->dev, state->cci_vreg, state->regulator_count, NULL, 0, &state->cci_reg_ptr[0], 1); ret = adv7481_parse_dt(state); if (ret < 0) { pr_err("%s:cci config_vreg failed\n", __func__); pr_err("Error parsing dt tree\n"); 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); ret = adv7481_cci_init(state); 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__); pr_err("%s: failed adv7481_cci_init ret %d\n", __func__, ret); goto err_mem_free; } Loading Loading @@ -2264,19 +2200,18 @@ static int adv7481_probe(struct platform_device *pdev) err_media_entity: media_entity_cleanup(&sd->entity); err_mem_free: kfree(state); devm_kfree(&pdev->dev, state); err: if (!ret) ret = 1; return ret; } static int adv7481_remove(struct platform_device *pdev) { struct adv7481_state *state; struct adv7481_state *state = platform_get_drvdata(pdev); state = pdev->dev.platform_data; msm_ba_unregister_subdev_node(&state->sd); v4l2_device_unregister_subdev(&state->sd); media_entity_cleanup(&state->sd.entity); Loading @@ -2289,7 +2224,7 @@ static int adv7481_remove(struct platform_device *pdev) cancel_delayed_work(&state->irq_delayed_work); mutex_destroy(&state->mutex); kfree(state); devm_kfree(&pdev->dev, state); return 0; } Loading Loading
Documentation/devicetree/bindings/arm/msm/adv7481.txt +9 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,9 @@ 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. - gpios: The GPIOs required to be configured for the driver. It should be in the order I2C data line, i2c clock line, reset line, interrupt 1, interrupt 2 and interrupt 3. Example: Loading @@ -17,4 +20,10 @@ Example: compatible = "qcom,adv7481"; qcom,cci-master = <0>; qcom,slave-addr = <0x70>; gpios = <&tlmm 17 0>, /* I2C SDA */ <&tlmm 18 0>, /* I2C SCL */ <&pm8994_gpios 4 0>, /* RST */ <&pm8994_gpios 5 0>, /* INT1 */ <&pm8994_gpios 6 0>, /* INT2 */ <&pm8994_gpios 7 0>; /* INT3 */ };
arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi +13 −8 Original line number Diff line number Diff line Loading @@ -698,14 +698,11 @@ }; &pm8994_gpios { gpio@c600 { /* GPIO 7 - NFC DWL REQ */ qcom,mode = <1>; qcom,output-type = <0>; qcom,pull = <5>; gpio@c600 { /* GPIO 7 - adv7481 INT3 */ qcom,mode = <0>; qcom,pull = <0>; qcom,vin-sel = <2>; qcom,out-strength = <3>; qcom,src-sel = <0>; qcom,master-en = <1>; status = "okay"; }; Loading Loading @@ -756,7 +753,15 @@ status = "okay"; }; gpio@c300 { /* GPIO 4 */ gpio@c300 { /* GPIO 4 - adv7481 RST */ qcom,mode = <1>; qcom,pull = <0>; qcom,vin-sel = <2>; qcom,src-sel = <0>; status = "okay"; }; gpio@c400 { /* GPIO 5 - adv7481 INT1 */ qcom,mode = <0>; qcom,pull = <0>; qcom,vin-sel = <2>; Loading @@ -764,7 +769,7 @@ status = "okay"; }; gpio@c400 { /* GPIO 5 */ gpio@c500 { /* GPIO 6 - adv7481 INT2*/ qcom,mode = <0>; qcom,pull = <0>; qcom,vin-sel = <2>; Loading
drivers/media/i2c/adv7481.c +34 −99 Original line number Diff line number Diff line Loading @@ -77,22 +77,12 @@ enum adv7481_gpio_t { }; 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; Loading Loading @@ -589,7 +579,7 @@ static int adv7481_dev_init(struct adv7481_state *state) 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); udelay(I2C_SW_RST_DELAY); chip_rev_id = adv7481_rd_word(&state->i2c_client, state->i2c_io_addr, IO_REG_CHIP_REV_ID_1_ADDR); Loading Loading @@ -678,12 +668,10 @@ static int adv7481_hw_init(struct adv7481_state *state) 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); udelay(GPIO_HW_RST_DELAY_LOW); 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); udelay(GPIO_HW_RST_DELAY_HI); if (ret) { pr_err("%s: Set GPIO Fail %d\n", __func__, ret); goto err_exit; Loading Loading @@ -2036,6 +2024,10 @@ static int adv7481_cci_init(struct adv7481_state *state) } cci_client->cci_subdev = msm_cci_get_subdev(); pr_debug("%s cci_subdev: %p\n", __func__, cci_client->cci_subdev); if (!cci_client->cci_subdev) { ret = -EPROBE_DEFER; goto err_cci_init; } cci_client->cci_i2c_master = state->cci_master; cci_client->sid = state->i2c_slave_addr; cci_client->retries = 3; Loading @@ -2056,77 +2048,47 @@ err_cci_init: static int adv7481_parse_dt(struct adv7481_state *state) { struct device_node *np = state->dev->of_node; unsigned int i; uint32_t i = 0; 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); pr_err("%s: failed to read cci master . 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); pr_err("%s: failed to read slave-addr. 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) { if (gpio_count != ADV7481_GPIO_MAX) { ret = -EFAULT; pr_err("%s: failed to configure GPIO ret -EFAULT\n", __func__); pr_err("%s: dt gpio count %d doesn't match required. ret %d\n", __func__, gpio_count, ret); 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); state->gpio_array[i].gpio = of_get_gpio_flags(np, i, (enum of_gpio_flags *)&state->gpio_array[i].flags); if (!gpio_is_valid(state->gpio_array[i].gpio)) { pr_err("invalid gpio setting for index %d\n", i); ret = -EFAULT; goto exit; } pr_debug("%s: gpio_array[%d] = %d flag = %ld\n", __func__, i, state->gpio_array[i].gpio, state->gpio_array[i].flags); } pr_debug("%s: End read back gpio from dt...", __func__); exit: return ret; Loading @@ -2142,7 +2104,6 @@ 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; int ret; Loading @@ -2160,44 +2121,19 @@ static int adv7481_probe(struct platform_device *pdev) ret = -ENOMEM; goto err; } platform_set_drvdata(pdev, state); state->dev = &pdev->dev; mutex_init(&state->mutex); /* 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; } ret = msm_camera_config_vreg(&pdev->dev, state->cci_vreg, state->regulator_count, NULL, 0, &state->cci_reg_ptr[0], 1); ret = adv7481_parse_dt(state); if (ret < 0) { pr_err("%s:cci config_vreg failed\n", __func__); pr_err("Error parsing dt tree\n"); 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); ret = adv7481_cci_init(state); 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__); pr_err("%s: failed adv7481_cci_init ret %d\n", __func__, ret); goto err_mem_free; } Loading Loading @@ -2264,19 +2200,18 @@ static int adv7481_probe(struct platform_device *pdev) err_media_entity: media_entity_cleanup(&sd->entity); err_mem_free: kfree(state); devm_kfree(&pdev->dev, state); err: if (!ret) ret = 1; return ret; } static int adv7481_remove(struct platform_device *pdev) { struct adv7481_state *state; struct adv7481_state *state = platform_get_drvdata(pdev); state = pdev->dev.platform_data; msm_ba_unregister_subdev_node(&state->sd); v4l2_device_unregister_subdev(&state->sd); media_entity_cleanup(&state->sd.entity); Loading @@ -2289,7 +2224,7 @@ static int adv7481_remove(struct platform_device *pdev) cancel_delayed_work(&state->irq_delayed_work); mutex_destroy(&state->mutex); kfree(state); devm_kfree(&pdev->dev, state); return 0; } Loading