summaryrefslogtreecommitdiff
path: root/drivers/media/i2c/s5c73m3/s5c73m3-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c/s5c73m3/s5c73m3-core.c')
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-core.c288
1 files changed, 110 insertions, 178 deletions
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index f434fb2ee6fc..ab31ee2b596b 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1,29 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Samsung LSI S5C73M3 8M pixel camera driver
*
* Copyright (C) 2012, Samsung Electronics, Co., Ltd.
* Sylwester Nawrocki <s.nawrocki@samsung.com>
* Andrzej Hajda <a.hajda@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/firmware.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/media.h>
#include <linux/module.h>
-#include <linux/of_gpio.h>
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <linux/sizes.h>
@@ -35,7 +26,6 @@
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
-#include <media/i2c/s5c73m3.h>
#include <media/v4l2-fwnode.h>
#include "s5c73m3.h"
@@ -248,17 +238,17 @@ static int s5c73m3_check_status(struct s5c73m3 *state, unsigned int value)
{
unsigned long start = jiffies;
unsigned long end = start + msecs_to_jiffies(2000);
- int ret = 0;
+ int ret;
u16 status;
int count = 0;
- while (time_is_after_jiffies(end)) {
+ do {
ret = s5c73m3_read(state, REG_STATUS, &status);
if (ret < 0 || status == value)
break;
usleep_range(500, 1000);
++count;
- }
+ } while (time_is_after_jiffies(end));
if (count > 0)
v4l2_dbg(1, s5c73m3_dbg, &state->sensor_sd,
@@ -445,7 +435,7 @@ static int __s5c73m3_s_stream(struct s5c73m3 *state, struct v4l2_subdev *sd,
state->streaming = !!on;
if (!on)
- return ret;
+ return 0;
if (state->apply_fiv) {
ret = s5c73m3_set_frame_rate(state);
@@ -825,11 +815,10 @@ static const struct s5c73m3_frame_size *s5c73m3_find_frame_size(
}
static void s5c73m3_oif_try_format(struct s5c73m3 *state,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt,
const struct s5c73m3_frame_size **fs)
{
- struct v4l2_subdev *sd = &state->sensor_sd;
u32 code;
switch (fmt->pad) {
@@ -851,10 +840,8 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state,
if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
*fs = state->oif_pix_size[RES_ISP];
else
- *fs = s5c73m3_find_frame_size(
- v4l2_subdev_get_try_format(sd, cfg,
- OIF_ISP_PAD),
- RES_ISP);
+ *fs = s5c73m3_find_frame_size(v4l2_subdev_state_get_format(sd_state, OIF_ISP_PAD),
+ RES_ISP);
break;
}
@@ -862,7 +849,7 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state,
}
static void s5c73m3_try_format(struct s5c73m3 *state,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt,
const struct s5c73m3_frame_size **fs)
{
@@ -879,11 +866,19 @@ static void s5c73m3_try_format(struct s5c73m3 *state,
s5c73m3_fill_mbus_fmt(&fmt->format, *fs, code);
}
-static int s5c73m3_oif_g_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_frame_interval *fi)
+static int s5c73m3_oif_get_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_interval *fi)
{
struct s5c73m3 *state = oif_sd_to_s5c73m3(sd);
+ /*
+ * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
+ * subdev active state API.
+ */
+ if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
+
if (fi->pad != OIF_SOURCE_PAD)
return -EINVAL;
@@ -928,12 +923,20 @@ static int __s5c73m3_set_frame_interval(struct s5c73m3 *state,
return 0;
}
-static int s5c73m3_oif_s_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_frame_interval *fi)
+static int s5c73m3_oif_set_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_interval *fi)
{
struct s5c73m3 *state = oif_sd_to_s5c73m3(sd);
int ret;
+ /*
+ * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
+ * subdev active state API.
+ */
+ if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
+
if (fi->pad != OIF_SOURCE_PAD)
return -EINVAL;
@@ -954,7 +957,7 @@ static int s5c73m3_oif_s_frame_interval(struct v4l2_subdev *sd,
}
static int s5c73m3_oif_enum_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval_enum *fie)
{
struct s5c73m3 *state = oif_sd_to_s5c73m3(sd);
@@ -992,7 +995,7 @@ static int s5c73m3_oif_get_pad_code(int pad, int index)
}
static int s5c73m3_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt)
{
struct s5c73m3 *state = sensor_sd_to_s5c73m3(sd);
@@ -1000,7 +1003,8 @@ static int s5c73m3_get_fmt(struct v4l2_subdev *sd,
u32 code;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+ fmt->format = *v4l2_subdev_state_get_format(sd_state,
+ fmt->pad);
return 0;
}
@@ -1026,7 +1030,7 @@ static int s5c73m3_get_fmt(struct v4l2_subdev *sd,
}
static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt)
{
struct s5c73m3 *state = oif_sd_to_s5c73m3(sd);
@@ -1034,7 +1038,8 @@ static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd,
u32 code;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+ fmt->format = *v4l2_subdev_state_get_format(sd_state,
+ fmt->pad);
return 0;
}
@@ -1064,7 +1069,7 @@ static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd,
}
static int s5c73m3_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt)
{
const struct s5c73m3_frame_size *frame_size = NULL;
@@ -1074,10 +1079,10 @@ static int s5c73m3_set_fmt(struct v4l2_subdev *sd,
mutex_lock(&state->lock);
- s5c73m3_try_format(state, cfg, fmt, &frame_size);
+ s5c73m3_try_format(state, sd_state, fmt, &frame_size);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+ mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*mf = fmt->format;
} else {
switch (fmt->pad) {
@@ -1103,7 +1108,7 @@ static int s5c73m3_set_fmt(struct v4l2_subdev *sd,
}
static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt)
{
const struct s5c73m3_frame_size *frame_size = NULL;
@@ -1113,13 +1118,14 @@ static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd,
mutex_lock(&state->lock);
- s5c73m3_oif_try_format(state, cfg, fmt, &frame_size);
+ s5c73m3_oif_try_format(state, sd_state, fmt, &frame_size);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+ mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*mf = fmt->format;
if (fmt->pad == OIF_ISP_PAD) {
- mf = v4l2_subdev_get_try_format(sd, cfg, OIF_SOURCE_PAD);
+ mf = v4l2_subdev_state_get_format(sd_state,
+ OIF_SOURCE_PAD);
mf->width = fmt->format.width;
mf->height = fmt->format.height;
}
@@ -1191,7 +1197,7 @@ static int s5c73m3_oif_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
}
static int s5c73m3_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{
static const int codes[] = {
@@ -1207,7 +1213,7 @@ static int s5c73m3_enum_mbus_code(struct v4l2_subdev *sd,
}
static int s5c73m3_oif_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{
int ret;
@@ -1222,7 +1228,7 @@ static int s5c73m3_oif_enum_mbus_code(struct v4l2_subdev *sd,
}
static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_size_enum *fse)
{
int idx;
@@ -1249,7 +1255,7 @@ static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd,
}
static int s5c73m3_oif_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_size_enum *fse)
{
struct s5c73m3 *state = oif_sd_to_s5c73m3(sd);
@@ -1267,8 +1273,8 @@ static int s5c73m3_oif_enum_frame_size(struct v4l2_subdev *sd,
if (fse->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *mf;
- mf = v4l2_subdev_get_try_format(sd, cfg,
- OIF_ISP_PAD);
+ mf = v4l2_subdev_state_get_format(sd_state,
+ OIF_ISP_PAD);
w = mf->width;
h = mf->height;
@@ -1323,11 +1329,11 @@ static int s5c73m3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
struct v4l2_mbus_framefmt *mf;
- mf = v4l2_subdev_get_try_format(sd, fh->pad, S5C73M3_ISP_PAD);
+ mf = v4l2_subdev_state_get_format(fh->state, S5C73M3_ISP_PAD);
s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1],
S5C73M3_ISP_FMT);
- mf = v4l2_subdev_get_try_format(sd, fh->pad, S5C73M3_JPEG_PAD);
+ mf = v4l2_subdev_state_get_format(fh->state, S5C73M3_JPEG_PAD);
s5c73m3_fill_mbus_fmt(mf, &s5c73m3_jpeg_resolutions[1],
S5C73M3_JPEG_FMT);
@@ -1338,38 +1344,20 @@ static int s5c73m3_oif_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
struct v4l2_mbus_framefmt *mf;
- mf = v4l2_subdev_get_try_format(sd, fh->pad, OIF_ISP_PAD);
+ mf = v4l2_subdev_state_get_format(fh->state, OIF_ISP_PAD);
s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1],
S5C73M3_ISP_FMT);
- mf = v4l2_subdev_get_try_format(sd, fh->pad, OIF_JPEG_PAD);
+ mf = v4l2_subdev_state_get_format(fh->state, OIF_JPEG_PAD);
s5c73m3_fill_mbus_fmt(mf, &s5c73m3_jpeg_resolutions[1],
S5C73M3_JPEG_FMT);
- mf = v4l2_subdev_get_try_format(sd, fh->pad, OIF_SOURCE_PAD);
+ mf = v4l2_subdev_state_get_format(fh->state, OIF_SOURCE_PAD);
s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1],
S5C73M3_ISP_FMT);
return 0;
}
-static int s5c73m3_gpio_set_value(struct s5c73m3 *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 s5c73m3_gpio_assert(struct s5c73m3 *priv, int id)
-{
- return s5c73m3_gpio_set_value(priv, id, priv->gpio[id].level);
-}
-
-static int s5c73m3_gpio_deassert(struct s5c73m3 *priv, int id)
-{
- return s5c73m3_gpio_set_value(priv, id, !priv->gpio[id].level);
-}
-
static int __s5c73m3_power_on(struct s5c73m3 *state)
{
int i, ret;
@@ -1380,10 +1368,6 @@ static int __s5c73m3_power_on(struct s5c73m3 *state)
goto err_reg_dis;
}
- ret = clk_set_rate(state->clock, state->mclk_frequency);
- if (ret < 0)
- goto err_reg_dis;
-
ret = clk_prepare_enable(state->clock);
if (ret < 0)
goto err_reg_dis;
@@ -1391,10 +1375,9 @@ static int __s5c73m3_power_on(struct s5c73m3 *state)
v4l2_dbg(1, s5c73m3_dbg, &state->oif_sd, "clock frequency: %ld\n",
clk_get_rate(state->clock));
- s5c73m3_gpio_deassert(state, STBY);
+ gpiod_set_value(state->stby, 0);
usleep_range(100, 200);
-
- s5c73m3_gpio_deassert(state, RST);
+ gpiod_set_value(state->reset, 0);
usleep_range(50, 100);
return 0;
@@ -1405,15 +1388,24 @@ err_reg_dis:
return ret;
}
+/*
+ * This function has been created just to avoid a smatch warning,
+ * please do not merge into __s5c73m3_power_off() until you have
+ * confirmed that it does not introduce a new warning.
+ */
+static void s5c73m3_enable_clk(struct s5c73m3 *state)
+{
+ clk_prepare_enable(state->clock);
+}
+
static int __s5c73m3_power_off(struct s5c73m3 *state)
{
int i, ret;
- if (s5c73m3_gpio_assert(state, RST))
- usleep_range(10, 50);
-
- if (s5c73m3_gpio_assert(state, STBY))
- usleep_range(100, 200);
+ gpiod_set_value(state->reset, 1);
+ usleep_range(10, 50);
+ gpiod_set_value(state->stby, 1);
+ usleep_range(100, 200);
clk_disable_unprepare(state->clock);
@@ -1431,11 +1423,12 @@ err:
for (++i; i < S5C73M3_MAX_SUPPLIES; i++) {
int r = regulator_enable(state->supplies[i].consumer);
if (r < 0)
- v4l2_err(&state->oif_sd, "Failed to reenable %s: %d\n",
+ v4l2_err(&state->oif_sd, "Failed to re-enable %s: %d\n",
state->supplies[i].supply, r);
}
- clk_prepare_enable(state->clock);
+ s5c73m3_enable_clk(state);
+
return ret;
}
@@ -1527,6 +1520,8 @@ static const struct v4l2_subdev_pad_ops s5c73m3_oif_pad_ops = {
.enum_frame_interval = s5c73m3_oif_enum_frame_interval,
.get_fmt = s5c73m3_oif_get_fmt,
.set_fmt = s5c73m3_oif_set_fmt,
+ .get_frame_interval = s5c73m3_oif_get_frame_interval,
+ .set_frame_interval = s5c73m3_oif_set_frame_interval,
.get_frame_desc = s5c73m3_oif_get_frame_desc,
.set_frame_desc = s5c73m3_oif_set_frame_desc,
};
@@ -1538,8 +1533,6 @@ static const struct v4l2_subdev_core_ops s5c73m3_oif_core_ops = {
static const struct v4l2_subdev_video_ops s5c73m3_oif_video_ops = {
.s_stream = s5c73m3_oif_s_stream,
- .g_frame_interval = s5c73m3_oif_g_frame_interval,
- .s_frame_interval = s5c73m3_oif_s_frame_interval,
};
static const struct v4l2_subdev_ops oif_subdev_ops = {
@@ -1548,95 +1541,40 @@ static const struct v4l2_subdev_ops oif_subdev_ops = {
.video = &s5c73m3_oif_video_ops,
};
-static int s5c73m3_configure_gpios(struct s5c73m3 *state)
+static int s5c73m3_get_dt_data(struct s5c73m3 *state)
{
- static const char * const gpio_names[] = {
- "S5C73M3_STBY", "S5C73M3_RST"
- };
- struct i2c_client *c = state->i2c_client;
- struct s5c73m3_gpio *g = state->gpio;
- int ret, i;
-
- for (i = 0; i < GPIO_NUM; ++i) {
- unsigned int flags = GPIOF_DIR_OUT;
- if (g[i].level)
- flags |= GPIOF_INIT_HIGH;
- ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags,
- gpio_names[i]);
- if (ret) {
- v4l2_err(c, "failed to request gpio %s\n",
- gpio_names[i]);
- return ret;
- }
- }
- return 0;
-}
-
-static int s5c73m3_parse_gpios(struct s5c73m3 *state)
-{
- static const char * const prop_names[] = {
- "standby-gpios", "xshutdown-gpios",
- };
struct device *dev = &state->i2c_client->dev;
struct device_node *node = dev->of_node;
- int ret, i;
-
- for (i = 0; i < GPIO_NUM; ++i) {
- enum of_gpio_flags of_flags;
-
- ret = of_get_named_gpio_flags(node, prop_names[i],
- 0, &of_flags);
- if (ret < 0) {
- dev_err(dev, "failed to parse %s DT property\n",
- prop_names[i]);
- return -EINVAL;
- }
- state->gpio[i].gpio = ret;
- state->gpio[i].level = !(of_flags & OF_GPIO_ACTIVE_LOW);
- }
- return 0;
-}
-
-static int s5c73m3_get_platform_data(struct s5c73m3 *state)
-{
- struct device *dev = &state->i2c_client->dev;
- const struct s5c73m3_platform_data *pdata = dev->platform_data;
- struct device_node *node = dev->of_node;
struct device_node *node_ep;
- struct v4l2_fwnode_endpoint ep;
+ struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
int ret;
- if (!node) {
- if (!pdata) {
- dev_err(dev, "Platform data not specified\n");
- return -EINVAL;
- }
-
- state->mclk_frequency = pdata->mclk_frequency;
- state->gpio[STBY] = pdata->gpio_stby;
- state->gpio[RST] = pdata->gpio_reset;
- return 0;
- }
-
- state->clock = devm_clk_get(dev, S5C73M3_CLK_NAME);
- if (IS_ERR(state->clock))
- return PTR_ERR(state->clock);
-
- if (of_property_read_u32(node, "clock-frequency",
- &state->mclk_frequency)) {
- state->mclk_frequency = S5C73M3_DEFAULT_MCLK_FREQ;
- dev_info(dev, "using default %u Hz clock frequency\n",
- state->mclk_frequency);
- }
-
- ret = s5c73m3_parse_gpios(state);
- if (ret < 0)
+ if (!node)
return -EINVAL;
- node_ep = of_graph_get_next_endpoint(node, NULL);
+ state->clock = devm_v4l2_sensor_clk_get_legacy(dev, S5C73M3_CLK_NAME,
+ false,
+ S5C73M3_DEFAULT_MCLK_FREQ);
+ if (IS_ERR(state->clock))
+ return dev_err_probe(dev, PTR_ERR(state->clock),
+ "Failed to get the clock %s\n",
+ S5C73M3_CLK_NAME);
+
+ /* Request GPIO lines asserted */
+ state->stby = devm_gpiod_get(dev, "standby", GPIOD_OUT_HIGH);
+ if (IS_ERR(state->stby))
+ return dev_err_probe(dev, PTR_ERR(state->stby),
+ "failed to request gpio S5C73M3_STBY\n");
+ gpiod_set_consumer_name(state->stby, "S5C73M3_STBY");
+ state->reset = devm_gpiod_get(dev, "xshutdown", GPIOD_OUT_HIGH);
+ if (IS_ERR(state->reset))
+ return dev_err_probe(dev, PTR_ERR(state->reset),
+ "failed to request gpio S5C73M3_RST\n");
+ gpiod_set_consumer_name(state->reset, "S5C73M3_RST");
+
+ node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
if (!node_ep) {
- dev_warn(dev, "no endpoint defined for node: %s\n",
- node->full_name);
+ dev_warn(dev, "no endpoint defined for node: %pOF\n", node);
return 0;
}
@@ -1645,7 +1583,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
if (ret)
return ret;
- if (ep.bus_type != V4L2_MBUS_CSI2) {
+ if (ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
dev_err(dev, "unsupported bus type\n");
return -EINVAL;
}
@@ -1659,8 +1597,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
return 0;
}
-static int s5c73m3_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int s5c73m3_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct v4l2_subdev *sd;
@@ -1673,7 +1610,7 @@ static int s5c73m3_probe(struct i2c_client *client,
return -ENOMEM;
state->i2c_client = client;
- ret = s5c73m3_get_platform_data(state);
+ ret = s5c73m3_get_dt_data(state);
if (ret < 0)
return ret;
@@ -1684,7 +1621,7 @@ static int s5c73m3_probe(struct i2c_client *client,
v4l2_subdev_init(sd, &s5c73m3_subdev_ops);
sd->owner = client->dev.driver->owner;
v4l2_set_subdevdata(sd, state);
- strlcpy(sd->name, "S5C73M3", sizeof(sd->name));
+ strscpy(sd->name, "S5C73M3", sizeof(sd->name));
sd->internal_ops = &s5c73m3_internal_ops;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -1699,7 +1636,8 @@ static int s5c73m3_probe(struct i2c_client *client,
return ret;
v4l2_i2c_subdev_init(oif_sd, client, &oif_subdev_ops);
- strcpy(oif_sd->name, "S5C73M3-OIF");
+ /* Static name; NEVER use in new drivers! */
+ strscpy(oif_sd->name, "S5C73M3-OIF", sizeof(oif_sd->name));
oif_sd->internal_ops = &oif_internal_ops;
oif_sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -1714,10 +1652,6 @@ static int s5c73m3_probe(struct i2c_client *client,
if (ret < 0)
return ret;
- ret = s5c73m3_configure_gpios(state);
- if (ret)
- goto out_err;
-
for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++)
state->supplies[i].supply = s5c73m3_supply_names[i];
@@ -1776,7 +1710,7 @@ out_err:
return ret;
}
-static int s5c73m3_remove(struct i2c_client *client)
+static void s5c73m3_remove(struct i2c_client *client)
{
struct v4l2_subdev *oif_sd = i2c_get_clientdata(client);
struct s5c73m3 *state = oif_sd_to_s5c73m3(oif_sd);
@@ -1791,12 +1725,10 @@ static int s5c73m3_remove(struct i2c_client *client)
media_entity_cleanup(&sensor_sd->entity);
s5c73m3_unregister_spi_driver(state);
-
- return 0;
}
static const struct i2c_device_id s5c73m3_id[] = {
- { DRIVER_NAME, 0 },
+ { DRIVER_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, s5c73m3_id);