The ds90ub953 supports GPIO0 through GPIO3. When enabled as an output,
each GPIO pin can be programed to output remote data coming from the
compatible deserializer using the register LOCAL_GPIO_DATA[7:4] field.
Add third cell for GPIO controller to select output source.
Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
---
drivers/media/i2c/ds90ub953.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c
index e3fc9d66970a762d284955f14db48d7105b4b8c4..274972cd21f9f0facd5098b724c0d6c661ce95c2 100644
--- a/drivers/media/i2c/ds90ub953.c
+++ b/drivers/media/i2c/ds90ub953.c
@@ -71,6 +71,7 @@ struct ub953_data {
bool non_continous_clk;
struct gpio_chip gpio_chip;
+ bool gpio_rmten[UB953_NUM_GPIOS];
struct v4l2_subdev sd;
struct media_pad pads[2];
@@ -288,13 +289,17 @@ static int ub953_gpio_direction_out(struct gpio_chip *gc, unsigned int offset,
int value)
{
struct ub953_data *priv = gpiochip_get_data(gc);
+ unsigned int val;
int ret;
- ret = regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA,
- UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset),
- value ? UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset) :
- 0);
+ val = priv->gpio_rmten[offset]
+ ? UB953_REG_LOCAL_GPIO_DATA_GPIO_RMTEN(offset)
+ : value ? UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset) : 0;
+ ret = regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA,
+ UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset) |
+ UB953_REG_LOCAL_GPIO_DATA_GPIO_RMTEN(offset),
+ val);
if (ret)
return ret;
@@ -320,6 +325,12 @@ static int ub953_gpio_get(struct gpio_chip *gc, unsigned int offset)
static int ub953_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
{
struct ub953_data *priv = gpiochip_get_data(gc);
+ struct device *dev = &priv->client->dev;
+
+ if (priv->gpio_rmten[offset]) {
+ dev_err(dev, "GPIO%u be programed to output remote data\n", offset);
+ return -EINVAL;
+ }
return regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA,
UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset),
@@ -330,10 +341,19 @@ static int ub953_gpio_of_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec,
u32 *flags)
{
+ struct ub953_data *priv = gpiochip_get_data(gc);
+ u32 line;
+
+ line = gpiospec->args[0];
+ if (line >= UB953_NUM_GPIOS)
+ return -EINVAL;
+
+ priv->gpio_rmten[line] = gpiospec->args[2] ? true : false;
+
if (flags)
*flags = gpiospec->args[1];
- return gpiospec->args[0];
+ return line;
}
static int ub953_gpiochip_probe(struct ub953_data *priv)
@@ -363,7 +383,7 @@ static int ub953_gpiochip_probe(struct ub953_data *priv)
gc->get = ub953_gpio_get;
gc->set = ub953_gpio_set;
gc->of_xlate = ub953_gpio_of_xlate;
- gc->of_gpio_n_cells = 2;
+ gc->of_gpio_n_cells = 3;
ret = gpiochip_add_data(gc, priv);
if (ret) {
--
2.34.1