^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Samsung S5K6A3 image sensor driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2013 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <media/v4l2-async.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <media/v4l2-subdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define S5K6A3_SENSOR_MAX_WIDTH 1412
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define S5K6A3_SENSOR_MAX_HEIGHT 1412
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define S5K6A3_SENSOR_MIN_WIDTH 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define S5K6A3_SENSOR_MIN_HEIGHT 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define S5K6A3_DEFAULT_WIDTH 1296
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define S5K6A3_DEFAULT_HEIGHT 732
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define S5K6A3_DRV_NAME "S5K6A3"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define S5K6A3_CLK_NAME "extclk"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define S5K6A3_DEFAULT_CLK_FREQ 24000000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) S5K6A3_SUPP_VDDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) S5K6A3_SUPP_VDDIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) S5K6A3_SUPP_AFVDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) S5K6A3_NUM_SUPPLIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * struct s5k6a3 - fimc-is sensor data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @dev: pointer to this I2C client device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @subdev: the image sensor's v4l2 subdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @pad: subdev media source pad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @supplies: image sensor's voltage regulator supplies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * @gpio_reset: GPIO connected to the sensor's reset pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * @lock: mutex protecting the structure's members below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * @format: media bus format at the sensor's source pad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @clock: pointer to &struct clk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @clock_frequency: clock frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @power_count: stores state if device is powered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct s5k6a3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct v4l2_subdev subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct media_pad pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct regulator_bulk_data supplies[S5K6A3_NUM_SUPPLIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int gpio_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct v4l2_mbus_framefmt format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct clk *clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u32 clock_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int power_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static const char * const s5k6a3_supply_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) [S5K6A3_SUPP_VDDA] = "svdda",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) [S5K6A3_SUPP_VDDIO] = "svddio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) [S5K6A3_SUPP_AFVDD] = "afvdd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static inline struct s5k6a3 *sd_to_s5k6a3(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return container_of(sd, struct s5k6a3, subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static const struct v4l2_mbus_framefmt s5k6a3_formats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .code = MEDIA_BUS_FMT_SGRBG10_1X10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .field = V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static const struct v4l2_mbus_framefmt *find_sensor_format(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct v4l2_mbus_framefmt *mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) for (i = 0; i < ARRAY_SIZE(s5k6a3_formats); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (mf->code == s5k6a3_formats[i].code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return &s5k6a3_formats[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return &s5k6a3_formats[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int s5k6a3_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (code->index >= ARRAY_SIZE(s5k6a3_formats))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) code->code = s5k6a3_formats[code->index].code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void s5k6a3_try_format(struct v4l2_mbus_framefmt *mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) const struct v4l2_mbus_framefmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) fmt = find_sensor_format(mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mf->code = fmt->code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mf->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) v4l_bound_align_image(&mf->width, S5K6A3_SENSOR_MIN_WIDTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) S5K6A3_SENSOR_MAX_WIDTH, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) &mf->height, S5K6A3_SENSOR_MIN_HEIGHT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) S5K6A3_SENSOR_MAX_HEIGHT, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static struct v4l2_mbus_framefmt *__s5k6a3_get_format(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct s5k6a3 *sensor, struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u32 pad, enum v4l2_subdev_format_whence which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (which == V4L2_SUBDEV_FORMAT_TRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return cfg ? v4l2_subdev_get_try_format(&sensor->subdev, cfg, pad) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return &sensor->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int s5k6a3_set_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct v4l2_mbus_framefmt *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) s5k6a3_try_format(&fmt->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) mf = __s5k6a3_get_format(sensor, cfg, fmt->pad, fmt->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (mf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) *mf = fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int s5k6a3_get_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct v4l2_mbus_framefmt *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mf = __s5k6a3_get_format(sensor, cfg, fmt->pad, fmt->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) fmt->format = *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static const struct v4l2_subdev_pad_ops s5k6a3_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .enum_mbus_code = s5k6a3_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .get_fmt = s5k6a3_get_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .set_fmt = s5k6a3_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int s5k6a3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *format = s5k6a3_formats[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) format->width = S5K6A3_DEFAULT_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) format->height = S5K6A3_DEFAULT_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static const struct v4l2_subdev_internal_ops s5k6a3_sd_internal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .open = s5k6a3_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static int __s5k6a3_power_on(struct s5k6a3 *sensor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int i = S5K6A3_SUPP_VDDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ret = clk_set_rate(sensor->clock, sensor->clock_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ret = pm_runtime_get(sensor->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) goto error_rpm_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ret = regulator_enable(sensor->supplies[i].consumer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto error_rpm_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ret = clk_prepare_enable(sensor->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) goto error_reg_dis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) for (i++; i < S5K6A3_NUM_SUPPLIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = regulator_enable(sensor->supplies[i].consumer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) goto error_reg_dis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) gpio_set_value(sensor->gpio_reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) usleep_range(600, 800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) gpio_set_value(sensor->gpio_reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) usleep_range(600, 800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) gpio_set_value(sensor->gpio_reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* Delay needed for the sensor initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) error_reg_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) for (--i; i >= 0; --i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) regulator_disable(sensor->supplies[i].consumer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) error_rpm_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pm_runtime_put(sensor->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int __s5k6a3_power_off(struct s5k6a3 *sensor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) gpio_set_value(sensor->gpio_reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) for (i = S5K6A3_NUM_SUPPLIES - 1; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) regulator_disable(sensor->supplies[i].consumer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) clk_disable_unprepare(sensor->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) pm_runtime_put(sensor->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int s5k6a3_s_power(struct v4l2_subdev *sd, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (sensor->power_count == !on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = __s5k6a3_power_on(sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = __s5k6a3_power_off(sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) sensor->power_count += on ? 1 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static const struct v4l2_subdev_core_ops s5k6a3_core_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .s_power = s5k6a3_s_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static const struct v4l2_subdev_ops s5k6a3_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .core = &s5k6a3_core_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .pad = &s5k6a3_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int s5k6a3_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct s5k6a3 *sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct v4l2_subdev *sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int gpio, i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!sensor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) mutex_init(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) sensor->gpio_reset = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) sensor->clock = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) sensor->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sensor->clock = devm_clk_get(sensor->dev, S5K6A3_CLK_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (IS_ERR(sensor->clock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return PTR_ERR(sensor->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) gpio = of_get_gpio_flags(dev->of_node, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (!gpio_is_valid(gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) S5K6A3_DRV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) sensor->gpio_reset = gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (of_property_read_u32(dev->of_node, "clock-frequency",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) &sensor->clock_frequency)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) sensor->clock_frequency = S5K6A3_DEFAULT_CLK_FREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dev_info(dev, "using default %u Hz clock frequency\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) sensor->clock_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) for (i = 0; i < S5K6A3_NUM_SUPPLIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) sensor->supplies[i].supply = s5k6a3_supply_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ret = devm_regulator_bulk_get(&client->dev, S5K6A3_NUM_SUPPLIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) sensor->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) sd = &sensor->subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) v4l2_i2c_subdev_init(sd, client, &s5k6a3_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) sd->internal_ops = &s5k6a3_sd_internal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) sensor->format.code = s5k6a3_formats[0].code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) sensor->format.width = S5K6A3_DEFAULT_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) sensor->format.height = S5K6A3_DEFAULT_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) pm_runtime_no_callbacks(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ret = v4l2_async_register_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static int s5k6a3_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) v4l2_async_unregister_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static const struct i2c_device_id s5k6a3_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) MODULE_DEVICE_TABLE(i2c, s5k6a3_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static const struct of_device_id s5k6a3_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) { .compatible = "samsung,s5k6a3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) MODULE_DEVICE_TABLE(of, s5k6a3_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static struct i2c_driver s5k6a3_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .of_match_table = of_match_ptr(s5k6a3_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .name = S5K6A3_DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .probe_new = s5k6a3_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .remove = s5k6a3_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .id_table = s5k6a3_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) module_i2c_driver(s5k6a3_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) MODULE_DESCRIPTION("S5K6A3 image sensor subdev driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) MODULE_LICENSE("GPL v2");