#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/firmware.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <asm/unaligned.h>
#include <media/media-entity.h>
-#include <media/i2c/s5k4ecgx.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
#define S5K4ECGX_NUM_SUPPLIES ARRAY_SIZE(s5k4ecgx_supply_names)
-enum s5k4ecgx_gpio_id {
- STBY,
- RSET,
- GPIO_NUM,
-};
-
struct s5k4ecgx {
struct v4l2_subdev sd;
struct media_pad pad;
u8 set_params;
struct regulator_bulk_data supplies[S5K4ECGX_NUM_SUPPLIES];
- struct s5k4ecgx_gpio gpio[GPIO_NUM];
+ struct gpio_desc *stby;
+ struct gpio_desc *reset;
};
static inline struct s5k4ecgx *to_s5k4ecgx(struct v4l2_subdev *sd)
return ret;
}
-static int s5k4ecgx_gpio_set_value(struct s5k4ecgx *priv, int id, u32 val)
-{
- if (!gpio_is_valid(priv->gpio[id].gpio))
- return 0;
- gpio_set_value(priv->gpio[id].gpio, val);
-
- return 1;
-}
-
static int __s5k4ecgx_power_on(struct s5k4ecgx *priv)
{
int ret;
return ret;
usleep_range(30, 50);
- /* The polarity of STBY is controlled by TSP */
- if (s5k4ecgx_gpio_set_value(priv, STBY, priv->gpio[STBY].level))
- usleep_range(30, 50);
-
- if (s5k4ecgx_gpio_set_value(priv, RSET, priv->gpio[RSET].level))
- usleep_range(30, 50);
+ gpiod_set_value(priv->stby, 0);
+ usleep_range(30, 50);
+ gpiod_set_value(priv->reset, 0);
+ usleep_range(30, 50);
return 0;
}
static int __s5k4ecgx_power_off(struct s5k4ecgx *priv)
{
- if (s5k4ecgx_gpio_set_value(priv, RSET, !priv->gpio[RSET].level))
- usleep_range(30, 50);
-
- if (s5k4ecgx_gpio_set_value(priv, STBY, !priv->gpio[STBY].level))
- usleep_range(30, 50);
+ gpiod_set_value(priv->reset, 1);
+ usleep_range(30, 50);
+ gpiod_set_value(priv->stby, 1);
+ usleep_range(30, 50);
priv->streaming = 0;
.video = &s5k4ecgx_video_ops,
};
-/*
- * GPIO setup
- */
-static int s5k4ecgx_config_gpio(int nr, int val, const char *name)
-{
- unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
- int ret;
-
- if (!gpio_is_valid(nr))
- return 0;
- ret = gpio_request_one(nr, flags, name);
- if (!ret)
- gpio_export(nr, 0);
-
- return ret;
-}
-
-static void s5k4ecgx_free_gpios(struct s5k4ecgx *priv)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(priv->gpio); i++) {
- if (!gpio_is_valid(priv->gpio[i].gpio))
- continue;
- gpio_free(priv->gpio[i].gpio);
- priv->gpio[i].gpio = -EINVAL;
- }
-}
-
-static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv,
- const struct s5k4ecgx_platform_data *pdata)
-{
- const struct s5k4ecgx_gpio *gpio = &pdata->gpio_stby;
- int ret;
-
- priv->gpio[STBY].gpio = -EINVAL;
- priv->gpio[RSET].gpio = -EINVAL;
-
- ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_STBY");
-
- if (ret) {
- s5k4ecgx_free_gpios(priv);
- return ret;
- }
- priv->gpio[STBY] = *gpio;
- if (gpio_is_valid(gpio->gpio))
- gpio_set_value(gpio->gpio, 0);
-
- gpio = &pdata->gpio_reset;
-
- ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_RST");
- if (ret) {
- s5k4ecgx_free_gpios(priv);
- return ret;
- }
- priv->gpio[RSET] = *gpio;
- if (gpio_is_valid(gpio->gpio))
- gpio_set_value(gpio->gpio, 0);
-
- return 0;
-}
-
static int s5k4ecgx_init_v4l2_ctrls(struct s5k4ecgx *priv)
{
const struct v4l2_ctrl_ops *ops = &s5k4ecgx_ctrl_ops;
if (ret)
return ret;
- ret = s5k4ecgx_config_gpios(priv, pdata);
- if (ret) {
- dev_err(&client->dev, "Failed to set gpios\n");
- goto out_err1;
- }
+ priv->stby = devm_gpiod_get(&client->dev, "standby", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->stby))
+ dev_err_probe(&client->dev, PTR_ERR(priv->stby),
+ "failed to request gpio S5K4ECGX_STBY\n");
+ gpiod_set_consumer_name(priv->stby, "S5K4ECGX_STBY");
+ priv->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->reset))
+ dev_err_probe(&client->dev, PTR_ERR(priv->reset),
+ "failed to request gpio S5K4ECGX_RST\n");
+ gpiod_set_consumer_name(priv->reset, "S5K4ECGX_RST");
+
for (i = 0; i < S5K4ECGX_NUM_SUPPLIES; i++)
priv->supplies[i].supply = s5k4ecgx_supply_names[i];
priv->supplies);
if (ret) {
dev_err(&client->dev, "Failed to get regulators\n");
- goto out_err2;
+ goto out_err;
}
ret = s5k4ecgx_init_v4l2_ctrls(priv);
if (ret)
- goto out_err2;
+ goto out_err;
priv->curr_pixfmt = &s5k4ecgx_formats[0];
priv->curr_frmsize = &s5k4ecgx_prev_sizes[0];
return 0;
-out_err2:
- s5k4ecgx_free_gpios(priv);
-out_err1:
+out_err:
media_entity_cleanup(&priv->sd.entity);
return ret;
struct s5k4ecgx *priv = to_s5k4ecgx(sd);
mutex_destroy(&priv->lock);
- s5k4ecgx_free_gpios(priv);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&priv->handler);
media_entity_cleanup(&sd->entity);