diff options
Diffstat (limited to 'drivers/media/i2c/ov5693.c')
| -rw-r--r-- | drivers/media/i2c/ov5693.c | 57 |
1 files changed, 38 insertions, 19 deletions
diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c index 117ff5403312..82a9b2de7735 100644 --- a/drivers/media/i2c/ov5693.c +++ b/drivers/media/i2c/ov5693.c @@ -127,11 +127,16 @@ #define OV5693_LINK_FREQ_419_2MHZ 419200000 #define OV5693_PIXEL_RATE 167680000 -/* Miscellaneous */ -#define OV5693_NUM_SUPPLIES 2 - #define to_ov5693_sensor(x) container_of(x, struct ov5693_device, sd) +static const char * const ov5693_supply_names[] = { + "avdd", /* Analog power */ + "dovdd", /* Digital I/O power */ + "dvdd", /* Digital circuit power */ +}; + +#define OV5693_NUM_SUPPLIES ARRAY_SIZE(ov5693_supply_names) + struct ov5693_reg { u32 reg; u8 val; @@ -152,7 +157,7 @@ struct ov5693_device { struct gpio_desc *reset; struct gpio_desc *powerdown; struct regulator_bulk_data supplies[OV5693_NUM_SUPPLIES]; - struct clk *clk; + struct clk *xvclk; struct ov5693_mode { struct v4l2_rect crop; @@ -352,11 +357,6 @@ static const s64 link_freq_menu_items[] = { OV5693_LINK_FREQ_419_2MHZ }; -static const char * const ov5693_supply_names[] = { - "avdd", - "dovdd", -}; - static const char * const ov5693_test_pattern_menu[] = { "Disabled", "Random Data", @@ -794,7 +794,7 @@ static void ov5693_sensor_powerdown(struct ov5693_device *ov5693) regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies); - clk_disable_unprepare(ov5693->clk); + clk_disable_unprepare(ov5693->xvclk); } static int ov5693_sensor_powerup(struct ov5693_device *ov5693) @@ -804,7 +804,7 @@ static int ov5693_sensor_powerup(struct ov5693_device *ov5693) gpiod_set_value_cansleep(ov5693->reset, 1); gpiod_set_value_cansleep(ov5693->powerdown, 1); - ret = clk_prepare_enable(ov5693->clk); + ret = clk_prepare_enable(ov5693->xvclk); if (ret) { dev_err(ov5693->dev, "Failed to enable clk\n"); goto fail_power; @@ -1390,7 +1390,7 @@ out_free_bus_cfg: static int ov5693_probe(struct i2c_client *client) { struct ov5693_device *ov5693; - u32 clk_rate; + u32 xvclk_rate; int ret = 0; ov5693 = devm_kzalloc(&client->dev, sizeof(*ov5693), GFP_KERNEL); @@ -1408,16 +1408,28 @@ static int ov5693_probe(struct i2c_client *client) v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops); - ov5693->clk = devm_clk_get(&client->dev, "xvclk"); - if (IS_ERR(ov5693->clk)) { - dev_err(&client->dev, "Error getting clock\n"); - return PTR_ERR(ov5693->clk); + ov5693->xvclk = devm_clk_get_optional(&client->dev, "xvclk"); + if (IS_ERR(ov5693->xvclk)) + return dev_err_probe(&client->dev, PTR_ERR(ov5693->xvclk), + "failed to get xvclk: %ld\n", + PTR_ERR(ov5693->xvclk)); + + if (ov5693->xvclk) { + xvclk_rate = clk_get_rate(ov5693->xvclk); + } else { + ret = fwnode_property_read_u32(dev_fwnode(&client->dev), + "clock-frequency", + &xvclk_rate); + + if (ret) { + dev_err(&client->dev, "can't get clock frequency"); + return ret; + } } - clk_rate = clk_get_rate(ov5693->clk); - if (clk_rate != OV5693_XVCLK_FREQ) + if (xvclk_rate != OV5693_XVCLK_FREQ) dev_warn(&client->dev, "Found clk freq %u, expected %u\n", - clk_rate, OV5693_XVCLK_FREQ); + xvclk_rate, OV5693_XVCLK_FREQ); ret = ov5693_configure_gpios(ov5693); if (ret) @@ -1521,10 +1533,17 @@ static const struct acpi_device_id ov5693_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, ov5693_acpi_match); +static const struct of_device_id ov5693_of_match[] = { + { .compatible = "ovti,ov5693", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, ov5693_of_match); + static struct i2c_driver ov5693_driver = { .driver = { .name = "ov5693", .acpi_match_table = ov5693_acpi_match, + .of_match_table = ov5693_of_match, .pm = &ov5693_pm_ops, }, .probe_new = ov5693_probe, |