diff --git a/drivers/media/i2c/maxim4c/maxim4c_drv.c b/drivers/media/i2c/maxim4c/maxim4c_drv.c index 60d8955daac4..3ae0603384e0 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_drv.c +++ b/drivers/media/i2c/maxim4c/maxim4c_drv.c @@ -29,6 +29,9 @@ * V2.03.00 * 1. remote device add the maxim4c prefix to driver name. * + * V2.04.00 + * 1. Add regulator supplier dependencies. + * */ #include #include @@ -58,10 +61,15 @@ #include "maxim4c_api.h" -#define DRIVER_VERSION KERNEL_VERSION(2, 0x03, 0x00) +#define DRIVER_VERSION KERNEL_VERSION(2, 0x04, 0x00) #define MAXIM4C_XVCLK_FREQ 25000000 +static const char *const maxim4c_supply_names[MAXIM4C_NUM_SUPPLIES] = { + "vcc1v2", + "vcc1v8", +}; + static int maxim4c_check_local_chipid(maxim4c_t *maxim4c) { struct i2c_client *client = maxim4c->client; @@ -302,6 +310,13 @@ static inline u32 maxim4c_cal_delay(u32 cycles) static int maxim4c_local_device_power_on(maxim4c_t *maxim4c) { struct device *dev = &maxim4c->client->dev; + int ret; + + ret = regulator_bulk_enable(MAXIM4C_NUM_SUPPLIES, maxim4c->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators\n"); + return -EINVAL; + } if (!IS_ERR(maxim4c->pwdn_gpio)) { dev_info(dev, "local device pwdn gpio on\n"); @@ -317,24 +332,30 @@ static int maxim4c_local_device_power_on(maxim4c_t *maxim4c) static void maxim4c_local_device_power_off(maxim4c_t *maxim4c) { struct device *dev = &maxim4c->client->dev; + int ret; if (!IS_ERR(maxim4c->pwdn_gpio)) { dev_info(dev, "local device pwdn gpio off\n"); gpiod_set_value_cansleep(maxim4c->pwdn_gpio, 0); } + + ret = regulator_bulk_disable(MAXIM4C_NUM_SUPPLIES, maxim4c->supplies); + if (ret < 0) { + dev_warn(dev, "Failed to disable regulators\n"); + } } static int maxim4c_remote_device_power_on(maxim4c_t *maxim4c) { struct device *dev = &maxim4c->client->dev; + int ret; - // remote PoC enable - if (!IS_ERR(maxim4c->pocen_gpio)) { - dev_info(dev, "remote device pocen gpio on\n"); - - gpiod_set_value_cansleep(maxim4c->pocen_gpio, 1); - usleep_range(5000, 10000); + dev_dbg(dev, "Turn PoC on\n"); + ret = regulator_enable(maxim4c->poc_regulator); + if (ret < 0) { + dev_err(dev, "Unable to turn PoC on\n"); + return ret; } return 0; @@ -343,13 +364,12 @@ static int maxim4c_remote_device_power_on(maxim4c_t *maxim4c) static int maxim4c_remote_device_power_off(maxim4c_t *maxim4c) { struct device *dev = &maxim4c->client->dev; + int ret; - // remote PoC enable - if (!IS_ERR(maxim4c->pocen_gpio)) { - dev_info(dev, "remote device pocen gpio off\n"); - - gpiod_set_value_cansleep(maxim4c->pocen_gpio, 0); - } + dev_dbg(dev, "Turn PoC off\n"); + ret = regulator_disable(maxim4c->poc_regulator); + if (ret < 0) + dev_warn(dev, "Unable to turn PoC off\n"); return 0; } @@ -581,6 +601,7 @@ static int maxim4c_probe(struct i2c_client *client, maxim4c_t *maxim4c = NULL; u32 chip_id; int ret = 0; + unsigned int i; dev_info(dev, "driver version: %02x.%02x.%02x", DRIVER_VERSION >> 16, (DRIVER_VERSION & 0xff00) >> 8, DRIVER_VERSION & 0x00ff); @@ -621,14 +642,37 @@ static int maxim4c_probe(struct i2c_client *client, if (IS_ERR(maxim4c->pwdn_gpio)) dev_warn(dev, "Failed to get pwdn-gpios, maybe no use\n"); - maxim4c->pocen_gpio = devm_gpiod_get(dev, "pocen", GPIOD_OUT_LOW); - if (IS_ERR(maxim4c->pocen_gpio)) - dev_warn(dev, "Failed to get pocen-gpios\n"); - maxim4c->lock_gpio = devm_gpiod_get(dev, "lock", GPIOD_IN); if (IS_ERR(maxim4c->lock_gpio)) dev_warn(dev, "Failed to get lock-gpios\n"); + for (i = 0; i < MAXIM4C_NUM_SUPPLIES; i++) + maxim4c->supplies[i].supply = maxim4c_supply_names[i]; + + ret = devm_regulator_bulk_get(dev, MAXIM4C_NUM_SUPPLIES, + maxim4c->supplies); + if (ret < 0) { + if (ret != -EPROBE_DEFER) + dev_err(dev, "Unable to get supply regulators\n"); + else + dev_warn(dev, "Get PoC regulator deferred\n"); + return ret; + } + + maxim4c->poc_regulator = devm_regulator_get(dev, "poc"); + if (IS_ERR(maxim4c->poc_regulator)) { + if (PTR_ERR(maxim4c->poc_regulator) != -EPROBE_DEFER) + dev_err(dev, "Unable to get PoC regulator (%ld)\n", + PTR_ERR(maxim4c->poc_regulator)); + else + dev_err(dev, "Get PoC regulator deferred\n"); + + ret = PTR_ERR(maxim4c->poc_regulator); +#if !MAXIM4C_TEST_PATTERN + return ret; +#endif + } + mutex_init(&maxim4c->mutex); ret = maxim4c_local_device_power_on(maxim4c); diff --git a/drivers/media/i2c/maxim4c/maxim4c_drv.h b/drivers/media/i2c/maxim4c/maxim4c_drv.h index 444f20f5d3e8..7ba49d42af4d 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_drv.h +++ b/drivers/media/i2c/maxim4c/maxim4c_drv.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,8 @@ #define MAX96712_CHIP_ID 0xA0 #define MAX96722_CHIP_ID 0xA1 +#define MAXIM4C_NUM_SUPPLIES 2 + enum { MAXIM4C_HOT_PLUG_OUT = 0, MAXIM4C_HOT_PLUG_IN, @@ -57,8 +60,9 @@ typedef struct maxim4c { struct i2c_client *client; struct clk *xvclk; struct gpio_desc *pwdn_gpio; - struct gpio_desc *pocen_gpio; struct gpio_desc *lock_gpio; + struct regulator_bulk_data supplies[MAXIM4C_NUM_SUPPLIES]; + struct regulator *poc_regulator; struct mutex mutex;