2 * Samsung S5K6A3 image sensor driver
4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
5 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
12 #include <linux/clk.h>
13 #include <linux/delay.h>
14 #include <linux/device.h>
15 #include <linux/errno.h>
16 #include <linux/gpio.h>
17 #include <linux/i2c.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/of_gpio.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/slab.h>
24 #include <linux/videodev2.h>
25 #include <media/v4l2-async.h>
26 #include <media/v4l2-subdev.h>
28 #define S5K6A3_SENSOR_MAX_WIDTH 1412
29 #define S5K6A3_SENSOR_MAX_HEIGHT 1412
30 #define S5K6A3_SENSOR_MIN_WIDTH 32
31 #define S5K6A3_SENSOR_MIN_HEIGHT 32
33 #define S5K6A3_DEFAULT_WIDTH 1296
34 #define S5K6A3_DEFAULT_HEIGHT 732
36 #define S5K6A3_DRV_NAME "S5K6A3"
37 #define S5K6A3_CLK_NAME "extclk"
38 #define S5K6A3_DEFAULT_CLK_FREQ 24000000U
48 * struct s5k6a3 - fimc-is sensor data structure
49 * @dev: pointer to this I2C client device structure
50 * @subdev: the image sensor's v4l2 subdev
51 * @pad: subdev media source pad
52 * @supplies: image sensor's voltage regulator supplies
53 * @gpio_reset: GPIO connected to the sensor's reset pin
54 * @lock: mutex protecting the structure's members below
55 * @format: media bus format at the sensor's source pad
56 * @clock: pointer to &struct clk.
57 * @clock_frequency: clock frequency
58 * @power_count: stores state if device is powered
62 struct v4l2_subdev subdev
;
64 struct regulator_bulk_data supplies
[S5K6A3_NUM_SUPPLIES
];
67 struct v4l2_mbus_framefmt format
;
73 static const char * const s5k6a3_supply_names
[] = {
74 [S5K6A3_SUPP_VDDA
] = "svdda",
75 [S5K6A3_SUPP_VDDIO
] = "svddio",
76 [S5K6A3_SUPP_AFVDD
] = "afvdd",
79 static inline struct s5k6a3
*sd_to_s5k6a3(struct v4l2_subdev
*sd
)
81 return container_of(sd
, struct s5k6a3
, subdev
);
84 static const struct v4l2_mbus_framefmt s5k6a3_formats
[] = {
86 .code
= MEDIA_BUS_FMT_SGRBG10_1X10
,
87 .colorspace
= V4L2_COLORSPACE_SRGB
,
88 .field
= V4L2_FIELD_NONE
,
92 static const struct v4l2_mbus_framefmt
*find_sensor_format(
93 struct v4l2_mbus_framefmt
*mf
)
97 for (i
= 0; i
< ARRAY_SIZE(s5k6a3_formats
); i
++)
98 if (mf
->code
== s5k6a3_formats
[i
].code
)
99 return &s5k6a3_formats
[i
];
101 return &s5k6a3_formats
[0];
104 static int s5k6a3_enum_mbus_code(struct v4l2_subdev
*sd
,
105 struct v4l2_subdev_pad_config
*cfg
,
106 struct v4l2_subdev_mbus_code_enum
*code
)
108 if (code
->index
>= ARRAY_SIZE(s5k6a3_formats
))
111 code
->code
= s5k6a3_formats
[code
->index
].code
;
115 static void s5k6a3_try_format(struct v4l2_mbus_framefmt
*mf
)
117 const struct v4l2_mbus_framefmt
*fmt
;
119 fmt
= find_sensor_format(mf
);
120 mf
->code
= fmt
->code
;
121 mf
->field
= V4L2_FIELD_NONE
;
122 v4l_bound_align_image(&mf
->width
, S5K6A3_SENSOR_MIN_WIDTH
,
123 S5K6A3_SENSOR_MAX_WIDTH
, 0,
124 &mf
->height
, S5K6A3_SENSOR_MIN_HEIGHT
,
125 S5K6A3_SENSOR_MAX_HEIGHT
, 0, 0);
128 static struct v4l2_mbus_framefmt
*__s5k6a3_get_format(
129 struct s5k6a3
*sensor
, struct v4l2_subdev_pad_config
*cfg
,
130 u32 pad
, enum v4l2_subdev_format_whence which
)
132 if (which
== V4L2_SUBDEV_FORMAT_TRY
)
133 return cfg
? v4l2_subdev_get_try_format(&sensor
->subdev
, cfg
, pad
) : NULL
;
135 return &sensor
->format
;
138 static int s5k6a3_set_fmt(struct v4l2_subdev
*sd
,
139 struct v4l2_subdev_pad_config
*cfg
,
140 struct v4l2_subdev_format
*fmt
)
142 struct s5k6a3
*sensor
= sd_to_s5k6a3(sd
);
143 struct v4l2_mbus_framefmt
*mf
;
145 s5k6a3_try_format(&fmt
->format
);
147 mf
= __s5k6a3_get_format(sensor
, cfg
, fmt
->pad
, fmt
->which
);
149 mutex_lock(&sensor
->lock
);
151 mutex_unlock(&sensor
->lock
);
156 static int s5k6a3_get_fmt(struct v4l2_subdev
*sd
,
157 struct v4l2_subdev_pad_config
*cfg
,
158 struct v4l2_subdev_format
*fmt
)
160 struct s5k6a3
*sensor
= sd_to_s5k6a3(sd
);
161 struct v4l2_mbus_framefmt
*mf
;
163 mf
= __s5k6a3_get_format(sensor
, cfg
, fmt
->pad
, fmt
->which
);
165 mutex_lock(&sensor
->lock
);
167 mutex_unlock(&sensor
->lock
);
171 static const struct v4l2_subdev_pad_ops s5k6a3_pad_ops
= {
172 .enum_mbus_code
= s5k6a3_enum_mbus_code
,
173 .get_fmt
= s5k6a3_get_fmt
,
174 .set_fmt
= s5k6a3_set_fmt
,
177 static int s5k6a3_open(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
)
179 struct v4l2_mbus_framefmt
*format
= v4l2_subdev_get_try_format(sd
, fh
->pad
, 0);
181 *format
= s5k6a3_formats
[0];
182 format
->width
= S5K6A3_DEFAULT_WIDTH
;
183 format
->height
= S5K6A3_DEFAULT_HEIGHT
;
188 static const struct v4l2_subdev_internal_ops s5k6a3_sd_internal_ops
= {
192 static int __s5k6a3_power_on(struct s5k6a3
*sensor
)
194 int i
= S5K6A3_SUPP_VDDA
;
197 ret
= clk_set_rate(sensor
->clock
, sensor
->clock_frequency
);
201 ret
= pm_runtime_get(sensor
->dev
);
205 ret
= regulator_enable(sensor
->supplies
[i
].consumer
);
209 ret
= clk_prepare_enable(sensor
->clock
);
213 for (i
++; i
< S5K6A3_NUM_SUPPLIES
; i
++) {
214 ret
= regulator_enable(sensor
->supplies
[i
].consumer
);
219 gpio_set_value(sensor
->gpio_reset
, 1);
220 usleep_range(600, 800);
221 gpio_set_value(sensor
->gpio_reset
, 0);
222 usleep_range(600, 800);
223 gpio_set_value(sensor
->gpio_reset
, 1);
225 /* Delay needed for the sensor initialization */
230 for (--i
; i
>= 0; --i
)
231 regulator_disable(sensor
->supplies
[i
].consumer
);
233 pm_runtime_put(sensor
->dev
);
237 static int __s5k6a3_power_off(struct s5k6a3
*sensor
)
241 gpio_set_value(sensor
->gpio_reset
, 0);
243 for (i
= S5K6A3_NUM_SUPPLIES
- 1; i
>= 0; i
--)
244 regulator_disable(sensor
->supplies
[i
].consumer
);
246 clk_disable_unprepare(sensor
->clock
);
247 pm_runtime_put(sensor
->dev
);
251 static int s5k6a3_s_power(struct v4l2_subdev
*sd
, int on
)
253 struct s5k6a3
*sensor
= sd_to_s5k6a3(sd
);
256 mutex_lock(&sensor
->lock
);
258 if (sensor
->power_count
== !on
) {
260 ret
= __s5k6a3_power_on(sensor
);
262 ret
= __s5k6a3_power_off(sensor
);
265 sensor
->power_count
+= on
? 1 : -1;
268 mutex_unlock(&sensor
->lock
);
272 static const struct v4l2_subdev_core_ops s5k6a3_core_ops
= {
273 .s_power
= s5k6a3_s_power
,
276 static const struct v4l2_subdev_ops s5k6a3_subdev_ops
= {
277 .core
= &s5k6a3_core_ops
,
278 .pad
= &s5k6a3_pad_ops
,
281 static int s5k6a3_probe(struct i2c_client
*client
,
282 const struct i2c_device_id
*id
)
284 struct device
*dev
= &client
->dev
;
285 struct s5k6a3
*sensor
;
286 struct v4l2_subdev
*sd
;
289 sensor
= devm_kzalloc(dev
, sizeof(*sensor
), GFP_KERNEL
);
293 mutex_init(&sensor
->lock
);
294 sensor
->gpio_reset
= -EINVAL
;
295 sensor
->clock
= ERR_PTR(-EINVAL
);
298 sensor
->clock
= devm_clk_get(sensor
->dev
, S5K6A3_CLK_NAME
);
299 if (IS_ERR(sensor
->clock
))
300 return PTR_ERR(sensor
->clock
);
302 gpio
= of_get_gpio_flags(dev
->of_node
, 0, NULL
);
303 if (!gpio_is_valid(gpio
))
306 ret
= devm_gpio_request_one(dev
, gpio
, GPIOF_OUT_INIT_LOW
,
311 sensor
->gpio_reset
= gpio
;
313 if (of_property_read_u32(dev
->of_node
, "clock-frequency",
314 &sensor
->clock_frequency
)) {
315 sensor
->clock_frequency
= S5K6A3_DEFAULT_CLK_FREQ
;
316 dev_info(dev
, "using default %u Hz clock frequency\n",
317 sensor
->clock_frequency
);
320 for (i
= 0; i
< S5K6A3_NUM_SUPPLIES
; i
++)
321 sensor
->supplies
[i
].supply
= s5k6a3_supply_names
[i
];
323 ret
= devm_regulator_bulk_get(&client
->dev
, S5K6A3_NUM_SUPPLIES
,
328 sd
= &sensor
->subdev
;
329 v4l2_i2c_subdev_init(sd
, client
, &s5k6a3_subdev_ops
);
330 sensor
->subdev
.flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
331 sd
->internal_ops
= &s5k6a3_sd_internal_ops
;
333 sensor
->format
.code
= s5k6a3_formats
[0].code
;
334 sensor
->format
.width
= S5K6A3_DEFAULT_WIDTH
;
335 sensor
->format
.height
= S5K6A3_DEFAULT_HEIGHT
;
337 sd
->entity
.function
= MEDIA_ENT_F_CAM_SENSOR
;
338 sensor
->pad
.flags
= MEDIA_PAD_FL_SOURCE
;
339 ret
= media_entity_pads_init(&sd
->entity
, 1, &sensor
->pad
);
343 pm_runtime_no_callbacks(dev
);
344 pm_runtime_enable(dev
);
346 ret
= v4l2_async_register_subdev(sd
);
349 pm_runtime_disable(&client
->dev
);
350 media_entity_cleanup(&sd
->entity
);
356 static int s5k6a3_remove(struct i2c_client
*client
)
358 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
360 pm_runtime_disable(&client
->dev
);
361 v4l2_async_unregister_subdev(sd
);
362 media_entity_cleanup(&sd
->entity
);
366 static const struct i2c_device_id s5k6a3_ids
[] = {
369 MODULE_DEVICE_TABLE(i2c
, s5k6a3_ids
);
372 static const struct of_device_id s5k6a3_of_match
[] = {
373 { .compatible
= "samsung,s5k6a3" },
376 MODULE_DEVICE_TABLE(of
, s5k6a3_of_match
);
379 static struct i2c_driver s5k6a3_driver
= {
381 .of_match_table
= of_match_ptr(s5k6a3_of_match
),
382 .name
= S5K6A3_DRV_NAME
,
384 .probe
= s5k6a3_probe
,
385 .remove
= s5k6a3_remove
,
386 .id_table
= s5k6a3_ids
,
389 module_i2c_driver(s5k6a3_driver
);
391 MODULE_DESCRIPTION("S5K6A3 image sensor subdev driver");
392 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
393 MODULE_LICENSE("GPL v2");