xref: /OK3568_Linux_fs/kernel/drivers/media/i2c/video-i2c.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * video-i2c.c - Support for I2C transport video devices
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2018 Matt Ranostay <matt.ranostay@konsulko.com>
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Supported:
8*4882a593Smuzhiyun  * - Panasonic AMG88xx Grid-Eye Sensors
9*4882a593Smuzhiyun  * - Melexis MLX90640 Thermal Cameras
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/delay.h>
13*4882a593Smuzhiyun #include <linux/freezer.h>
14*4882a593Smuzhiyun #include <linux/hwmon.h>
15*4882a593Smuzhiyun #include <linux/kthread.h>
16*4882a593Smuzhiyun #include <linux/i2c.h>
17*4882a593Smuzhiyun #include <linux/list.h>
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <linux/mutex.h>
20*4882a593Smuzhiyun #include <linux/of_device.h>
21*4882a593Smuzhiyun #include <linux/pm_runtime.h>
22*4882a593Smuzhiyun #include <linux/nvmem-provider.h>
23*4882a593Smuzhiyun #include <linux/regmap.h>
24*4882a593Smuzhiyun #include <linux/sched.h>
25*4882a593Smuzhiyun #include <linux/slab.h>
26*4882a593Smuzhiyun #include <linux/videodev2.h>
27*4882a593Smuzhiyun #include <media/v4l2-common.h>
28*4882a593Smuzhiyun #include <media/v4l2-device.h>
29*4882a593Smuzhiyun #include <media/v4l2-event.h>
30*4882a593Smuzhiyun #include <media/v4l2-fh.h>
31*4882a593Smuzhiyun #include <media/v4l2-ioctl.h>
32*4882a593Smuzhiyun #include <media/videobuf2-v4l2.h>
33*4882a593Smuzhiyun #include <media/videobuf2-vmalloc.h>
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #define VIDEO_I2C_DRIVER	"video-i2c"
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun struct video_i2c_chip;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun struct video_i2c_buffer {
40*4882a593Smuzhiyun 	struct vb2_v4l2_buffer vb;
41*4882a593Smuzhiyun 	struct list_head list;
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun struct video_i2c_data {
45*4882a593Smuzhiyun 	struct regmap *regmap;
46*4882a593Smuzhiyun 	const struct video_i2c_chip *chip;
47*4882a593Smuzhiyun 	struct mutex lock;
48*4882a593Smuzhiyun 	spinlock_t slock;
49*4882a593Smuzhiyun 	unsigned int sequence;
50*4882a593Smuzhiyun 	struct mutex queue_lock;
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	struct v4l2_device v4l2_dev;
53*4882a593Smuzhiyun 	struct video_device vdev;
54*4882a593Smuzhiyun 	struct vb2_queue vb_vidq;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	struct task_struct *kthread_vid_cap;
57*4882a593Smuzhiyun 	struct list_head vid_cap_active;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	struct v4l2_fract frame_interval;
60*4882a593Smuzhiyun };
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun static const struct v4l2_fmtdesc amg88xx_format = {
63*4882a593Smuzhiyun 	.pixelformat = V4L2_PIX_FMT_Y12,
64*4882a593Smuzhiyun };
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun static const struct v4l2_frmsize_discrete amg88xx_size = {
67*4882a593Smuzhiyun 	.width = 8,
68*4882a593Smuzhiyun 	.height = 8,
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun static const struct v4l2_fmtdesc mlx90640_format = {
72*4882a593Smuzhiyun 	.pixelformat = V4L2_PIX_FMT_Y16_BE,
73*4882a593Smuzhiyun };
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun static const struct v4l2_frmsize_discrete mlx90640_size = {
76*4882a593Smuzhiyun 	.width = 32,
77*4882a593Smuzhiyun 	.height = 26, /* 24 lines of pixel data + 2 lines of processing data */
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun static const struct regmap_config amg88xx_regmap_config = {
81*4882a593Smuzhiyun 	.reg_bits = 8,
82*4882a593Smuzhiyun 	.val_bits = 8,
83*4882a593Smuzhiyun 	.max_register = 0xff
84*4882a593Smuzhiyun };
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun static const struct regmap_config mlx90640_regmap_config = {
87*4882a593Smuzhiyun 	.reg_bits = 16,
88*4882a593Smuzhiyun 	.val_bits = 16,
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun struct video_i2c_chip {
92*4882a593Smuzhiyun 	/* video dimensions */
93*4882a593Smuzhiyun 	const struct v4l2_fmtdesc *format;
94*4882a593Smuzhiyun 	const struct v4l2_frmsize_discrete *size;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	/* available frame intervals */
97*4882a593Smuzhiyun 	const struct v4l2_fract *frame_intervals;
98*4882a593Smuzhiyun 	unsigned int num_frame_intervals;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	/* pixel buffer size */
101*4882a593Smuzhiyun 	unsigned int buffer_size;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	/* pixel size in bits */
104*4882a593Smuzhiyun 	unsigned int bpp;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	const struct regmap_config *regmap_config;
107*4882a593Smuzhiyun 	struct nvmem_config *nvmem_config;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	/* setup function */
110*4882a593Smuzhiyun 	int (*setup)(struct video_i2c_data *data);
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	/* xfer function */
113*4882a593Smuzhiyun 	int (*xfer)(struct video_i2c_data *data, char *buf);
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	/* power control function */
116*4882a593Smuzhiyun 	int (*set_power)(struct video_i2c_data *data, bool on);
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	/* hwmon init function */
119*4882a593Smuzhiyun 	int (*hwmon_init)(struct video_i2c_data *data);
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun 
mlx90640_nvram_read(void * priv,unsigned int offset,void * val,size_t bytes)122*4882a593Smuzhiyun static int mlx90640_nvram_read(void *priv, unsigned int offset, void *val,
123*4882a593Smuzhiyun 			     size_t bytes)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	struct video_i2c_data *data = priv;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	return regmap_bulk_read(data->regmap, 0x2400 + offset, val, bytes);
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun static struct nvmem_config mlx90640_nvram_config = {
131*4882a593Smuzhiyun 	.name = "mlx90640_nvram",
132*4882a593Smuzhiyun 	.word_size = 2,
133*4882a593Smuzhiyun 	.stride = 1,
134*4882a593Smuzhiyun 	.size = 1664,
135*4882a593Smuzhiyun 	.reg_read = mlx90640_nvram_read,
136*4882a593Smuzhiyun };
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun /* Power control register */
139*4882a593Smuzhiyun #define AMG88XX_REG_PCTL	0x00
140*4882a593Smuzhiyun #define AMG88XX_PCTL_NORMAL		0x00
141*4882a593Smuzhiyun #define AMG88XX_PCTL_SLEEP		0x10
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun /* Reset register */
144*4882a593Smuzhiyun #define AMG88XX_REG_RST		0x01
145*4882a593Smuzhiyun #define AMG88XX_RST_FLAG		0x30
146*4882a593Smuzhiyun #define AMG88XX_RST_INIT		0x3f
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun /* Frame rate register */
149*4882a593Smuzhiyun #define AMG88XX_REG_FPSC	0x02
150*4882a593Smuzhiyun #define AMG88XX_FPSC_1FPS		BIT(0)
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun /* Thermistor register */
153*4882a593Smuzhiyun #define AMG88XX_REG_TTHL	0x0e
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun /* Temperature register */
156*4882a593Smuzhiyun #define AMG88XX_REG_T01L	0x80
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun /* Control register */
159*4882a593Smuzhiyun #define MLX90640_REG_CTL1		0x800d
160*4882a593Smuzhiyun #define MLX90640_REG_CTL1_MASK		0x0380
161*4882a593Smuzhiyun #define MLX90640_REG_CTL1_MASK_SHIFT	7
162*4882a593Smuzhiyun 
amg88xx_xfer(struct video_i2c_data * data,char * buf)163*4882a593Smuzhiyun static int amg88xx_xfer(struct video_i2c_data *data, char *buf)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	return regmap_bulk_read(data->regmap, AMG88XX_REG_T01L, buf,
166*4882a593Smuzhiyun 				data->chip->buffer_size);
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun 
mlx90640_xfer(struct video_i2c_data * data,char * buf)169*4882a593Smuzhiyun static int mlx90640_xfer(struct video_i2c_data *data, char *buf)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	return regmap_bulk_read(data->regmap, 0x400, buf,
172*4882a593Smuzhiyun 				data->chip->buffer_size);
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
amg88xx_setup(struct video_i2c_data * data)175*4882a593Smuzhiyun static int amg88xx_setup(struct video_i2c_data *data)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	unsigned int mask = AMG88XX_FPSC_1FPS;
178*4882a593Smuzhiyun 	unsigned int val;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	if (data->frame_interval.numerator == data->frame_interval.denominator)
181*4882a593Smuzhiyun 		val = mask;
182*4882a593Smuzhiyun 	else
183*4882a593Smuzhiyun 		val = 0;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	return regmap_update_bits(data->regmap, AMG88XX_REG_FPSC, mask, val);
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun 
mlx90640_setup(struct video_i2c_data * data)188*4882a593Smuzhiyun static int mlx90640_setup(struct video_i2c_data *data)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	unsigned int n, idx;
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	for (n = 0; n < data->chip->num_frame_intervals - 1; n++) {
193*4882a593Smuzhiyun 		if (V4L2_FRACT_COMPARE(data->frame_interval, ==,
194*4882a593Smuzhiyun 				       data->chip->frame_intervals[n]))
195*4882a593Smuzhiyun 			break;
196*4882a593Smuzhiyun 	}
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	idx = data->chip->num_frame_intervals - n - 1;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	return regmap_update_bits(data->regmap, MLX90640_REG_CTL1,
201*4882a593Smuzhiyun 				  MLX90640_REG_CTL1_MASK,
202*4882a593Smuzhiyun 				  idx << MLX90640_REG_CTL1_MASK_SHIFT);
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
amg88xx_set_power_on(struct video_i2c_data * data)205*4882a593Smuzhiyun static int amg88xx_set_power_on(struct video_i2c_data *data)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	int ret;
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	ret = regmap_write(data->regmap, AMG88XX_REG_PCTL, AMG88XX_PCTL_NORMAL);
210*4882a593Smuzhiyun 	if (ret)
211*4882a593Smuzhiyun 		return ret;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	msleep(50);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	ret = regmap_write(data->regmap, AMG88XX_REG_RST, AMG88XX_RST_INIT);
216*4882a593Smuzhiyun 	if (ret)
217*4882a593Smuzhiyun 		return ret;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	usleep_range(2000, 3000);
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	ret = regmap_write(data->regmap, AMG88XX_REG_RST, AMG88XX_RST_FLAG);
222*4882a593Smuzhiyun 	if (ret)
223*4882a593Smuzhiyun 		return ret;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	/*
226*4882a593Smuzhiyun 	 * Wait two frames before reading thermistor and temperature registers
227*4882a593Smuzhiyun 	 */
228*4882a593Smuzhiyun 	msleep(200);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	return 0;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
amg88xx_set_power_off(struct video_i2c_data * data)233*4882a593Smuzhiyun static int amg88xx_set_power_off(struct video_i2c_data *data)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun 	int ret;
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	ret = regmap_write(data->regmap, AMG88XX_REG_PCTL, AMG88XX_PCTL_SLEEP);
238*4882a593Smuzhiyun 	if (ret)
239*4882a593Smuzhiyun 		return ret;
240*4882a593Smuzhiyun 	/*
241*4882a593Smuzhiyun 	 * Wait for a while to avoid resuming normal mode immediately after
242*4882a593Smuzhiyun 	 * entering sleep mode, otherwise the device occasionally goes wrong
243*4882a593Smuzhiyun 	 * (thermistor and temperature registers are not updated at all)
244*4882a593Smuzhiyun 	 */
245*4882a593Smuzhiyun 	msleep(100);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	return 0;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun 
amg88xx_set_power(struct video_i2c_data * data,bool on)250*4882a593Smuzhiyun static int amg88xx_set_power(struct video_i2c_data *data, bool on)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun 	if (on)
253*4882a593Smuzhiyun 		return amg88xx_set_power_on(data);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	return amg88xx_set_power_off(data);
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun #if IS_REACHABLE(CONFIG_HWMON)
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun static const u32 amg88xx_temp_config[] = {
261*4882a593Smuzhiyun 	HWMON_T_INPUT,
262*4882a593Smuzhiyun 	0
263*4882a593Smuzhiyun };
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun static const struct hwmon_channel_info amg88xx_temp = {
266*4882a593Smuzhiyun 	.type = hwmon_temp,
267*4882a593Smuzhiyun 	.config = amg88xx_temp_config,
268*4882a593Smuzhiyun };
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun static const struct hwmon_channel_info *amg88xx_info[] = {
271*4882a593Smuzhiyun 	&amg88xx_temp,
272*4882a593Smuzhiyun 	NULL
273*4882a593Smuzhiyun };
274*4882a593Smuzhiyun 
amg88xx_is_visible(const void * drvdata,enum hwmon_sensor_types type,u32 attr,int channel)275*4882a593Smuzhiyun static umode_t amg88xx_is_visible(const void *drvdata,
276*4882a593Smuzhiyun 				  enum hwmon_sensor_types type,
277*4882a593Smuzhiyun 				  u32 attr, int channel)
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun 	return 0444;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun 
amg88xx_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)282*4882a593Smuzhiyun static int amg88xx_read(struct device *dev, enum hwmon_sensor_types type,
283*4882a593Smuzhiyun 			u32 attr, int channel, long *val)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	struct video_i2c_data *data = dev_get_drvdata(dev);
286*4882a593Smuzhiyun 	__le16 buf;
287*4882a593Smuzhiyun 	int tmp;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	tmp = pm_runtime_get_sync(regmap_get_device(data->regmap));
290*4882a593Smuzhiyun 	if (tmp < 0) {
291*4882a593Smuzhiyun 		pm_runtime_put_noidle(regmap_get_device(data->regmap));
292*4882a593Smuzhiyun 		return tmp;
293*4882a593Smuzhiyun 	}
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	tmp = regmap_bulk_read(data->regmap, AMG88XX_REG_TTHL, &buf, 2);
296*4882a593Smuzhiyun 	pm_runtime_mark_last_busy(regmap_get_device(data->regmap));
297*4882a593Smuzhiyun 	pm_runtime_put_autosuspend(regmap_get_device(data->regmap));
298*4882a593Smuzhiyun 	if (tmp)
299*4882a593Smuzhiyun 		return tmp;
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	tmp = le16_to_cpu(buf);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	/*
304*4882a593Smuzhiyun 	 * Check for sign bit, this isn't a two's complement value but an
305*4882a593Smuzhiyun 	 * absolute temperature that needs to be inverted in the case of being
306*4882a593Smuzhiyun 	 * negative.
307*4882a593Smuzhiyun 	 */
308*4882a593Smuzhiyun 	if (tmp & BIT(11))
309*4882a593Smuzhiyun 		tmp = -(tmp & 0x7ff);
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	*val = (tmp * 625) / 10;
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	return 0;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun static const struct hwmon_ops amg88xx_hwmon_ops = {
317*4882a593Smuzhiyun 	.is_visible = amg88xx_is_visible,
318*4882a593Smuzhiyun 	.read = amg88xx_read,
319*4882a593Smuzhiyun };
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun static const struct hwmon_chip_info amg88xx_chip_info = {
322*4882a593Smuzhiyun 	.ops = &amg88xx_hwmon_ops,
323*4882a593Smuzhiyun 	.info = amg88xx_info,
324*4882a593Smuzhiyun };
325*4882a593Smuzhiyun 
amg88xx_hwmon_init(struct video_i2c_data * data)326*4882a593Smuzhiyun static int amg88xx_hwmon_init(struct video_i2c_data *data)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun 	struct device *dev = regmap_get_device(data->regmap);
329*4882a593Smuzhiyun 	void *hwmon = devm_hwmon_device_register_with_info(dev, "amg88xx", data,
330*4882a593Smuzhiyun 						&amg88xx_chip_info, NULL);
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	return PTR_ERR_OR_ZERO(hwmon);
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun #else
335*4882a593Smuzhiyun #define	amg88xx_hwmon_init	NULL
336*4882a593Smuzhiyun #endif
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun enum {
339*4882a593Smuzhiyun 	AMG88XX,
340*4882a593Smuzhiyun 	MLX90640,
341*4882a593Smuzhiyun };
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun static const struct v4l2_fract amg88xx_frame_intervals[] = {
344*4882a593Smuzhiyun 	{ 1, 10 },
345*4882a593Smuzhiyun 	{ 1, 1 },
346*4882a593Smuzhiyun };
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun static const struct v4l2_fract mlx90640_frame_intervals[] = {
349*4882a593Smuzhiyun 	{ 1, 64 },
350*4882a593Smuzhiyun 	{ 1, 32 },
351*4882a593Smuzhiyun 	{ 1, 16 },
352*4882a593Smuzhiyun 	{ 1, 8 },
353*4882a593Smuzhiyun 	{ 1, 4 },
354*4882a593Smuzhiyun 	{ 1, 2 },
355*4882a593Smuzhiyun 	{ 1, 1 },
356*4882a593Smuzhiyun 	{ 2, 1 },
357*4882a593Smuzhiyun };
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun static const struct video_i2c_chip video_i2c_chip[] = {
360*4882a593Smuzhiyun 	[AMG88XX] = {
361*4882a593Smuzhiyun 		.size		= &amg88xx_size,
362*4882a593Smuzhiyun 		.format		= &amg88xx_format,
363*4882a593Smuzhiyun 		.frame_intervals	= amg88xx_frame_intervals,
364*4882a593Smuzhiyun 		.num_frame_intervals	= ARRAY_SIZE(amg88xx_frame_intervals),
365*4882a593Smuzhiyun 		.buffer_size	= 128,
366*4882a593Smuzhiyun 		.bpp		= 16,
367*4882a593Smuzhiyun 		.regmap_config	= &amg88xx_regmap_config,
368*4882a593Smuzhiyun 		.setup		= &amg88xx_setup,
369*4882a593Smuzhiyun 		.xfer		= &amg88xx_xfer,
370*4882a593Smuzhiyun 		.set_power	= amg88xx_set_power,
371*4882a593Smuzhiyun 		.hwmon_init	= amg88xx_hwmon_init,
372*4882a593Smuzhiyun 	},
373*4882a593Smuzhiyun 	[MLX90640] = {
374*4882a593Smuzhiyun 		.size		= &mlx90640_size,
375*4882a593Smuzhiyun 		.format		= &mlx90640_format,
376*4882a593Smuzhiyun 		.frame_intervals	= mlx90640_frame_intervals,
377*4882a593Smuzhiyun 		.num_frame_intervals	= ARRAY_SIZE(mlx90640_frame_intervals),
378*4882a593Smuzhiyun 		.buffer_size	= 1664,
379*4882a593Smuzhiyun 		.bpp		= 16,
380*4882a593Smuzhiyun 		.regmap_config	= &mlx90640_regmap_config,
381*4882a593Smuzhiyun 		.nvmem_config	= &mlx90640_nvram_config,
382*4882a593Smuzhiyun 		.setup		= mlx90640_setup,
383*4882a593Smuzhiyun 		.xfer		= mlx90640_xfer,
384*4882a593Smuzhiyun 	},
385*4882a593Smuzhiyun };
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun static const struct v4l2_file_operations video_i2c_fops = {
388*4882a593Smuzhiyun 	.owner		= THIS_MODULE,
389*4882a593Smuzhiyun 	.open		= v4l2_fh_open,
390*4882a593Smuzhiyun 	.release	= vb2_fop_release,
391*4882a593Smuzhiyun 	.poll		= vb2_fop_poll,
392*4882a593Smuzhiyun 	.read		= vb2_fop_read,
393*4882a593Smuzhiyun 	.mmap		= vb2_fop_mmap,
394*4882a593Smuzhiyun 	.unlocked_ioctl = video_ioctl2,
395*4882a593Smuzhiyun };
396*4882a593Smuzhiyun 
queue_setup(struct vb2_queue * vq,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_devs[])397*4882a593Smuzhiyun static int queue_setup(struct vb2_queue *vq,
398*4882a593Smuzhiyun 		       unsigned int *nbuffers, unsigned int *nplanes,
399*4882a593Smuzhiyun 		       unsigned int sizes[], struct device *alloc_devs[])
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun 	struct video_i2c_data *data = vb2_get_drv_priv(vq);
402*4882a593Smuzhiyun 	unsigned int size = data->chip->buffer_size;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	if (vq->num_buffers + *nbuffers < 2)
405*4882a593Smuzhiyun 		*nbuffers = 2;
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	if (*nplanes)
408*4882a593Smuzhiyun 		return sizes[0] < size ? -EINVAL : 0;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	*nplanes = 1;
411*4882a593Smuzhiyun 	sizes[0] = size;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	return 0;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
buffer_prepare(struct vb2_buffer * vb)416*4882a593Smuzhiyun static int buffer_prepare(struct vb2_buffer *vb)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
419*4882a593Smuzhiyun 	struct video_i2c_data *data = vb2_get_drv_priv(vb->vb2_queue);
420*4882a593Smuzhiyun 	unsigned int size = data->chip->buffer_size;
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	if (vb2_plane_size(vb, 0) < size)
423*4882a593Smuzhiyun 		return -EINVAL;
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	vbuf->field = V4L2_FIELD_NONE;
426*4882a593Smuzhiyun 	vb2_set_plane_payload(vb, 0, size);
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	return 0;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
buffer_queue(struct vb2_buffer * vb)431*4882a593Smuzhiyun static void buffer_queue(struct vb2_buffer *vb)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
434*4882a593Smuzhiyun 	struct video_i2c_data *data = vb2_get_drv_priv(vb->vb2_queue);
435*4882a593Smuzhiyun 	struct video_i2c_buffer *buf =
436*4882a593Smuzhiyun 			container_of(vbuf, struct video_i2c_buffer, vb);
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	spin_lock(&data->slock);
439*4882a593Smuzhiyun 	list_add_tail(&buf->list, &data->vid_cap_active);
440*4882a593Smuzhiyun 	spin_unlock(&data->slock);
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun 
video_i2c_thread_vid_cap(void * priv)443*4882a593Smuzhiyun static int video_i2c_thread_vid_cap(void *priv)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun 	struct video_i2c_data *data = priv;
446*4882a593Smuzhiyun 	unsigned int delay = mult_frac(HZ, data->frame_interval.numerator,
447*4882a593Smuzhiyun 				       data->frame_interval.denominator);
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	set_freezable();
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	do {
452*4882a593Smuzhiyun 		unsigned long start_jiffies = jiffies;
453*4882a593Smuzhiyun 		struct video_i2c_buffer *vid_cap_buf = NULL;
454*4882a593Smuzhiyun 		int schedule_delay;
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 		try_to_freeze();
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 		spin_lock(&data->slock);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 		if (!list_empty(&data->vid_cap_active)) {
461*4882a593Smuzhiyun 			vid_cap_buf = list_last_entry(&data->vid_cap_active,
462*4882a593Smuzhiyun 						 struct video_i2c_buffer, list);
463*4882a593Smuzhiyun 			list_del(&vid_cap_buf->list);
464*4882a593Smuzhiyun 		}
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 		spin_unlock(&data->slock);
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 		if (vid_cap_buf) {
469*4882a593Smuzhiyun 			struct vb2_buffer *vb2_buf = &vid_cap_buf->vb.vb2_buf;
470*4882a593Smuzhiyun 			void *vbuf = vb2_plane_vaddr(vb2_buf, 0);
471*4882a593Smuzhiyun 			int ret;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 			ret = data->chip->xfer(data, vbuf);
474*4882a593Smuzhiyun 			vb2_buf->timestamp = ktime_get_ns();
475*4882a593Smuzhiyun 			vid_cap_buf->vb.sequence = data->sequence++;
476*4882a593Smuzhiyun 			vb2_buffer_done(vb2_buf, ret ?
477*4882a593Smuzhiyun 				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
478*4882a593Smuzhiyun 		}
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 		schedule_delay = delay - (jiffies - start_jiffies);
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 		if (time_after(jiffies, start_jiffies + delay))
483*4882a593Smuzhiyun 			schedule_delay = delay;
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 		schedule_timeout_interruptible(schedule_delay);
486*4882a593Smuzhiyun 	} while (!kthread_should_stop());
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	return 0;
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun 
video_i2c_del_list(struct vb2_queue * vq,enum vb2_buffer_state state)491*4882a593Smuzhiyun static void video_i2c_del_list(struct vb2_queue *vq, enum vb2_buffer_state state)
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun 	struct video_i2c_data *data = vb2_get_drv_priv(vq);
494*4882a593Smuzhiyun 	struct video_i2c_buffer *buf, *tmp;
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	spin_lock(&data->slock);
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	list_for_each_entry_safe(buf, tmp, &data->vid_cap_active, list) {
499*4882a593Smuzhiyun 		list_del(&buf->list);
500*4882a593Smuzhiyun 		vb2_buffer_done(&buf->vb.vb2_buf, state);
501*4882a593Smuzhiyun 	}
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	spin_unlock(&data->slock);
504*4882a593Smuzhiyun }
505*4882a593Smuzhiyun 
start_streaming(struct vb2_queue * vq,unsigned int count)506*4882a593Smuzhiyun static int start_streaming(struct vb2_queue *vq, unsigned int count)
507*4882a593Smuzhiyun {
508*4882a593Smuzhiyun 	struct video_i2c_data *data = vb2_get_drv_priv(vq);
509*4882a593Smuzhiyun 	struct device *dev = regmap_get_device(data->regmap);
510*4882a593Smuzhiyun 	int ret;
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 	if (data->kthread_vid_cap)
513*4882a593Smuzhiyun 		return 0;
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	ret = pm_runtime_get_sync(dev);
516*4882a593Smuzhiyun 	if (ret < 0) {
517*4882a593Smuzhiyun 		pm_runtime_put_noidle(dev);
518*4882a593Smuzhiyun 		goto error_del_list;
519*4882a593Smuzhiyun 	}
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	ret = data->chip->setup(data);
522*4882a593Smuzhiyun 	if (ret)
523*4882a593Smuzhiyun 		goto error_rpm_put;
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	data->sequence = 0;
526*4882a593Smuzhiyun 	data->kthread_vid_cap = kthread_run(video_i2c_thread_vid_cap, data,
527*4882a593Smuzhiyun 					    "%s-vid-cap", data->v4l2_dev.name);
528*4882a593Smuzhiyun 	ret = PTR_ERR_OR_ZERO(data->kthread_vid_cap);
529*4882a593Smuzhiyun 	if (!ret)
530*4882a593Smuzhiyun 		return 0;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun error_rpm_put:
533*4882a593Smuzhiyun 	pm_runtime_mark_last_busy(dev);
534*4882a593Smuzhiyun 	pm_runtime_put_autosuspend(dev);
535*4882a593Smuzhiyun error_del_list:
536*4882a593Smuzhiyun 	video_i2c_del_list(vq, VB2_BUF_STATE_QUEUED);
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	return ret;
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun 
stop_streaming(struct vb2_queue * vq)541*4882a593Smuzhiyun static void stop_streaming(struct vb2_queue *vq)
542*4882a593Smuzhiyun {
543*4882a593Smuzhiyun 	struct video_i2c_data *data = vb2_get_drv_priv(vq);
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 	if (data->kthread_vid_cap == NULL)
546*4882a593Smuzhiyun 		return;
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	kthread_stop(data->kthread_vid_cap);
549*4882a593Smuzhiyun 	data->kthread_vid_cap = NULL;
550*4882a593Smuzhiyun 	pm_runtime_mark_last_busy(regmap_get_device(data->regmap));
551*4882a593Smuzhiyun 	pm_runtime_put_autosuspend(regmap_get_device(data->regmap));
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	video_i2c_del_list(vq, VB2_BUF_STATE_ERROR);
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun static const struct vb2_ops video_i2c_video_qops = {
557*4882a593Smuzhiyun 	.queue_setup		= queue_setup,
558*4882a593Smuzhiyun 	.buf_prepare		= buffer_prepare,
559*4882a593Smuzhiyun 	.buf_queue		= buffer_queue,
560*4882a593Smuzhiyun 	.start_streaming	= start_streaming,
561*4882a593Smuzhiyun 	.stop_streaming		= stop_streaming,
562*4882a593Smuzhiyun 	.wait_prepare		= vb2_ops_wait_prepare,
563*4882a593Smuzhiyun 	.wait_finish		= vb2_ops_wait_finish,
564*4882a593Smuzhiyun };
565*4882a593Smuzhiyun 
video_i2c_querycap(struct file * file,void * priv,struct v4l2_capability * vcap)566*4882a593Smuzhiyun static int video_i2c_querycap(struct file *file, void  *priv,
567*4882a593Smuzhiyun 				struct v4l2_capability *vcap)
568*4882a593Smuzhiyun {
569*4882a593Smuzhiyun 	struct video_i2c_data *data = video_drvdata(file);
570*4882a593Smuzhiyun 	struct device *dev = regmap_get_device(data->regmap);
571*4882a593Smuzhiyun 	struct i2c_client *client = to_i2c_client(dev);
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	strscpy(vcap->driver, data->v4l2_dev.name, sizeof(vcap->driver));
574*4882a593Smuzhiyun 	strscpy(vcap->card, data->vdev.name, sizeof(vcap->card));
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	sprintf(vcap->bus_info, "I2C:%d-%d", client->adapter->nr, client->addr);
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	return 0;
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun 
video_i2c_g_input(struct file * file,void * fh,unsigned int * inp)581*4882a593Smuzhiyun static int video_i2c_g_input(struct file *file, void *fh, unsigned int *inp)
582*4882a593Smuzhiyun {
583*4882a593Smuzhiyun 	*inp = 0;
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	return 0;
586*4882a593Smuzhiyun }
587*4882a593Smuzhiyun 
video_i2c_s_input(struct file * file,void * fh,unsigned int inp)588*4882a593Smuzhiyun static int video_i2c_s_input(struct file *file, void *fh, unsigned int inp)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun 	return (inp > 0) ? -EINVAL : 0;
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun 
video_i2c_enum_input(struct file * file,void * fh,struct v4l2_input * vin)593*4882a593Smuzhiyun static int video_i2c_enum_input(struct file *file, void *fh,
594*4882a593Smuzhiyun 				  struct v4l2_input *vin)
595*4882a593Smuzhiyun {
596*4882a593Smuzhiyun 	if (vin->index > 0)
597*4882a593Smuzhiyun 		return -EINVAL;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	strscpy(vin->name, "Camera", sizeof(vin->name));
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 	vin->type = V4L2_INPUT_TYPE_CAMERA;
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	return 0;
604*4882a593Smuzhiyun }
605*4882a593Smuzhiyun 
video_i2c_enum_fmt_vid_cap(struct file * file,void * fh,struct v4l2_fmtdesc * fmt)606*4882a593Smuzhiyun static int video_i2c_enum_fmt_vid_cap(struct file *file, void *fh,
607*4882a593Smuzhiyun 					struct v4l2_fmtdesc *fmt)
608*4882a593Smuzhiyun {
609*4882a593Smuzhiyun 	struct video_i2c_data *data = video_drvdata(file);
610*4882a593Smuzhiyun 	enum v4l2_buf_type type = fmt->type;
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	if (fmt->index > 0)
613*4882a593Smuzhiyun 		return -EINVAL;
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun 	*fmt = *data->chip->format;
616*4882a593Smuzhiyun 	fmt->type = type;
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	return 0;
619*4882a593Smuzhiyun }
620*4882a593Smuzhiyun 
video_i2c_enum_framesizes(struct file * file,void * fh,struct v4l2_frmsizeenum * fsize)621*4882a593Smuzhiyun static int video_i2c_enum_framesizes(struct file *file, void *fh,
622*4882a593Smuzhiyun 				       struct v4l2_frmsizeenum *fsize)
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun 	const struct video_i2c_data *data = video_drvdata(file);
625*4882a593Smuzhiyun 	const struct v4l2_frmsize_discrete *size = data->chip->size;
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	/* currently only one frame size is allowed */
628*4882a593Smuzhiyun 	if (fsize->index > 0)
629*4882a593Smuzhiyun 		return -EINVAL;
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 	if (fsize->pixel_format != data->chip->format->pixelformat)
632*4882a593Smuzhiyun 		return -EINVAL;
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
635*4882a593Smuzhiyun 	fsize->discrete.width = size->width;
636*4882a593Smuzhiyun 	fsize->discrete.height = size->height;
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 	return 0;
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun 
video_i2c_enum_frameintervals(struct file * file,void * priv,struct v4l2_frmivalenum * fe)641*4882a593Smuzhiyun static int video_i2c_enum_frameintervals(struct file *file, void *priv,
642*4882a593Smuzhiyun 					   struct v4l2_frmivalenum *fe)
643*4882a593Smuzhiyun {
644*4882a593Smuzhiyun 	const struct video_i2c_data *data = video_drvdata(file);
645*4882a593Smuzhiyun 	const struct v4l2_frmsize_discrete *size = data->chip->size;
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 	if (fe->index >= data->chip->num_frame_intervals)
648*4882a593Smuzhiyun 		return -EINVAL;
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 	if (fe->width != size->width || fe->height != size->height)
651*4882a593Smuzhiyun 		return -EINVAL;
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
654*4882a593Smuzhiyun 	fe->discrete = data->chip->frame_intervals[fe->index];
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun 	return 0;
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun 
video_i2c_try_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)659*4882a593Smuzhiyun static int video_i2c_try_fmt_vid_cap(struct file *file, void *fh,
660*4882a593Smuzhiyun 				       struct v4l2_format *fmt)
661*4882a593Smuzhiyun {
662*4882a593Smuzhiyun 	const struct video_i2c_data *data = video_drvdata(file);
663*4882a593Smuzhiyun 	const struct v4l2_frmsize_discrete *size = data->chip->size;
664*4882a593Smuzhiyun 	struct v4l2_pix_format *pix = &fmt->fmt.pix;
665*4882a593Smuzhiyun 	unsigned int bpp = data->chip->bpp / 8;
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	pix->width = size->width;
668*4882a593Smuzhiyun 	pix->height = size->height;
669*4882a593Smuzhiyun 	pix->pixelformat = data->chip->format->pixelformat;
670*4882a593Smuzhiyun 	pix->field = V4L2_FIELD_NONE;
671*4882a593Smuzhiyun 	pix->bytesperline = pix->width * bpp;
672*4882a593Smuzhiyun 	pix->sizeimage = pix->bytesperline * pix->height;
673*4882a593Smuzhiyun 	pix->colorspace = V4L2_COLORSPACE_RAW;
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	return 0;
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun 
video_i2c_s_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)678*4882a593Smuzhiyun static int video_i2c_s_fmt_vid_cap(struct file *file, void *fh,
679*4882a593Smuzhiyun 				     struct v4l2_format *fmt)
680*4882a593Smuzhiyun {
681*4882a593Smuzhiyun 	struct video_i2c_data *data = video_drvdata(file);
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	if (vb2_is_busy(&data->vb_vidq))
684*4882a593Smuzhiyun 		return -EBUSY;
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 	return video_i2c_try_fmt_vid_cap(file, fh, fmt);
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun 
video_i2c_g_parm(struct file * filp,void * priv,struct v4l2_streamparm * parm)689*4882a593Smuzhiyun static int video_i2c_g_parm(struct file *filp, void *priv,
690*4882a593Smuzhiyun 			      struct v4l2_streamparm *parm)
691*4882a593Smuzhiyun {
692*4882a593Smuzhiyun 	struct video_i2c_data *data = video_drvdata(filp);
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
695*4882a593Smuzhiyun 		return -EINVAL;
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	parm->parm.capture.readbuffers = 1;
698*4882a593Smuzhiyun 	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
699*4882a593Smuzhiyun 	parm->parm.capture.timeperframe = data->frame_interval;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	return 0;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun 
video_i2c_s_parm(struct file * filp,void * priv,struct v4l2_streamparm * parm)704*4882a593Smuzhiyun static int video_i2c_s_parm(struct file *filp, void *priv,
705*4882a593Smuzhiyun 			      struct v4l2_streamparm *parm)
706*4882a593Smuzhiyun {
707*4882a593Smuzhiyun 	struct video_i2c_data *data = video_drvdata(filp);
708*4882a593Smuzhiyun 	int i;
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	for (i = 0; i < data->chip->num_frame_intervals - 1; i++) {
711*4882a593Smuzhiyun 		if (V4L2_FRACT_COMPARE(parm->parm.capture.timeperframe, <=,
712*4882a593Smuzhiyun 				       data->chip->frame_intervals[i]))
713*4882a593Smuzhiyun 			break;
714*4882a593Smuzhiyun 	}
715*4882a593Smuzhiyun 	data->frame_interval = data->chip->frame_intervals[i];
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	return video_i2c_g_parm(filp, priv, parm);
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun static const struct v4l2_ioctl_ops video_i2c_ioctl_ops = {
721*4882a593Smuzhiyun 	.vidioc_querycap		= video_i2c_querycap,
722*4882a593Smuzhiyun 	.vidioc_g_input			= video_i2c_g_input,
723*4882a593Smuzhiyun 	.vidioc_s_input			= video_i2c_s_input,
724*4882a593Smuzhiyun 	.vidioc_enum_input		= video_i2c_enum_input,
725*4882a593Smuzhiyun 	.vidioc_enum_fmt_vid_cap	= video_i2c_enum_fmt_vid_cap,
726*4882a593Smuzhiyun 	.vidioc_enum_framesizes		= video_i2c_enum_framesizes,
727*4882a593Smuzhiyun 	.vidioc_enum_frameintervals	= video_i2c_enum_frameintervals,
728*4882a593Smuzhiyun 	.vidioc_g_fmt_vid_cap		= video_i2c_try_fmt_vid_cap,
729*4882a593Smuzhiyun 	.vidioc_s_fmt_vid_cap		= video_i2c_s_fmt_vid_cap,
730*4882a593Smuzhiyun 	.vidioc_g_parm			= video_i2c_g_parm,
731*4882a593Smuzhiyun 	.vidioc_s_parm			= video_i2c_s_parm,
732*4882a593Smuzhiyun 	.vidioc_try_fmt_vid_cap		= video_i2c_try_fmt_vid_cap,
733*4882a593Smuzhiyun 	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
734*4882a593Smuzhiyun 	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
735*4882a593Smuzhiyun 	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
736*4882a593Smuzhiyun 	.vidioc_querybuf		= vb2_ioctl_querybuf,
737*4882a593Smuzhiyun 	.vidioc_qbuf			= vb2_ioctl_qbuf,
738*4882a593Smuzhiyun 	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
739*4882a593Smuzhiyun 	.vidioc_streamon		= vb2_ioctl_streamon,
740*4882a593Smuzhiyun 	.vidioc_streamoff		= vb2_ioctl_streamoff,
741*4882a593Smuzhiyun };
742*4882a593Smuzhiyun 
video_i2c_release(struct video_device * vdev)743*4882a593Smuzhiyun static void video_i2c_release(struct video_device *vdev)
744*4882a593Smuzhiyun {
745*4882a593Smuzhiyun 	struct video_i2c_data *data = video_get_drvdata(vdev);
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 	v4l2_device_unregister(&data->v4l2_dev);
748*4882a593Smuzhiyun 	mutex_destroy(&data->lock);
749*4882a593Smuzhiyun 	mutex_destroy(&data->queue_lock);
750*4882a593Smuzhiyun 	regmap_exit(data->regmap);
751*4882a593Smuzhiyun 	kfree(data);
752*4882a593Smuzhiyun }
753*4882a593Smuzhiyun 
video_i2c_probe(struct i2c_client * client,const struct i2c_device_id * id)754*4882a593Smuzhiyun static int video_i2c_probe(struct i2c_client *client,
755*4882a593Smuzhiyun 			     const struct i2c_device_id *id)
756*4882a593Smuzhiyun {
757*4882a593Smuzhiyun 	struct video_i2c_data *data;
758*4882a593Smuzhiyun 	struct v4l2_device *v4l2_dev;
759*4882a593Smuzhiyun 	struct vb2_queue *queue;
760*4882a593Smuzhiyun 	int ret = -ENODEV;
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	data = kzalloc(sizeof(*data), GFP_KERNEL);
763*4882a593Smuzhiyun 	if (!data)
764*4882a593Smuzhiyun 		return -ENOMEM;
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun 	if (dev_fwnode(&client->dev))
767*4882a593Smuzhiyun 		data->chip = device_get_match_data(&client->dev);
768*4882a593Smuzhiyun 	else if (id)
769*4882a593Smuzhiyun 		data->chip = &video_i2c_chip[id->driver_data];
770*4882a593Smuzhiyun 	else
771*4882a593Smuzhiyun 		goto error_free_device;
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun 	data->regmap = regmap_init_i2c(client, data->chip->regmap_config);
774*4882a593Smuzhiyun 	if (IS_ERR(data->regmap)) {
775*4882a593Smuzhiyun 		ret = PTR_ERR(data->regmap);
776*4882a593Smuzhiyun 		goto error_free_device;
777*4882a593Smuzhiyun 	}
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 	v4l2_dev = &data->v4l2_dev;
780*4882a593Smuzhiyun 	strscpy(v4l2_dev->name, VIDEO_I2C_DRIVER, sizeof(v4l2_dev->name));
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	ret = v4l2_device_register(&client->dev, v4l2_dev);
783*4882a593Smuzhiyun 	if (ret < 0)
784*4882a593Smuzhiyun 		goto error_regmap_exit;
785*4882a593Smuzhiyun 
786*4882a593Smuzhiyun 	mutex_init(&data->lock);
787*4882a593Smuzhiyun 	mutex_init(&data->queue_lock);
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	queue = &data->vb_vidq;
790*4882a593Smuzhiyun 	queue->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
791*4882a593Smuzhiyun 	queue->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR | VB2_READ;
792*4882a593Smuzhiyun 	queue->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
793*4882a593Smuzhiyun 	queue->drv_priv = data;
794*4882a593Smuzhiyun 	queue->buf_struct_size = sizeof(struct video_i2c_buffer);
795*4882a593Smuzhiyun 	queue->min_buffers_needed = 1;
796*4882a593Smuzhiyun 	queue->ops = &video_i2c_video_qops;
797*4882a593Smuzhiyun 	queue->mem_ops = &vb2_vmalloc_memops;
798*4882a593Smuzhiyun 
799*4882a593Smuzhiyun 	ret = vb2_queue_init(queue);
800*4882a593Smuzhiyun 	if (ret < 0)
801*4882a593Smuzhiyun 		goto error_unregister_device;
802*4882a593Smuzhiyun 
803*4882a593Smuzhiyun 	data->vdev.queue = queue;
804*4882a593Smuzhiyun 	data->vdev.queue->lock = &data->queue_lock;
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 	snprintf(data->vdev.name, sizeof(data->vdev.name),
807*4882a593Smuzhiyun 				 "I2C %d-%d Transport Video",
808*4882a593Smuzhiyun 				 client->adapter->nr, client->addr);
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun 	data->vdev.v4l2_dev = v4l2_dev;
811*4882a593Smuzhiyun 	data->vdev.fops = &video_i2c_fops;
812*4882a593Smuzhiyun 	data->vdev.lock = &data->lock;
813*4882a593Smuzhiyun 	data->vdev.ioctl_ops = &video_i2c_ioctl_ops;
814*4882a593Smuzhiyun 	data->vdev.release = video_i2c_release;
815*4882a593Smuzhiyun 	data->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE |
816*4882a593Smuzhiyun 				 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun 	spin_lock_init(&data->slock);
819*4882a593Smuzhiyun 	INIT_LIST_HEAD(&data->vid_cap_active);
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 	data->frame_interval = data->chip->frame_intervals[0];
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun 	video_set_drvdata(&data->vdev, data);
824*4882a593Smuzhiyun 	i2c_set_clientdata(client, data);
825*4882a593Smuzhiyun 
826*4882a593Smuzhiyun 	if (data->chip->set_power) {
827*4882a593Smuzhiyun 		ret = data->chip->set_power(data, true);
828*4882a593Smuzhiyun 		if (ret)
829*4882a593Smuzhiyun 			goto error_unregister_device;
830*4882a593Smuzhiyun 	}
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun 	pm_runtime_get_noresume(&client->dev);
833*4882a593Smuzhiyun 	pm_runtime_set_active(&client->dev);
834*4882a593Smuzhiyun 	pm_runtime_enable(&client->dev);
835*4882a593Smuzhiyun 	pm_runtime_set_autosuspend_delay(&client->dev, 2000);
836*4882a593Smuzhiyun 	pm_runtime_use_autosuspend(&client->dev);
837*4882a593Smuzhiyun 
838*4882a593Smuzhiyun 	if (data->chip->hwmon_init) {
839*4882a593Smuzhiyun 		ret = data->chip->hwmon_init(data);
840*4882a593Smuzhiyun 		if (ret < 0) {
841*4882a593Smuzhiyun 			dev_warn(&client->dev,
842*4882a593Smuzhiyun 				 "failed to register hwmon device\n");
843*4882a593Smuzhiyun 		}
844*4882a593Smuzhiyun 	}
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun 	if (data->chip->nvmem_config) {
847*4882a593Smuzhiyun 		struct nvmem_config *config = data->chip->nvmem_config;
848*4882a593Smuzhiyun 		struct nvmem_device *device;
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 		config->priv = data;
851*4882a593Smuzhiyun 		config->dev = &client->dev;
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 		device = devm_nvmem_register(&client->dev, config);
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun 		if (IS_ERR(device)) {
856*4882a593Smuzhiyun 			dev_warn(&client->dev,
857*4882a593Smuzhiyun 				 "failed to register nvmem device\n");
858*4882a593Smuzhiyun 		}
859*4882a593Smuzhiyun 	}
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun 	ret = video_register_device(&data->vdev, VFL_TYPE_VIDEO, -1);
862*4882a593Smuzhiyun 	if (ret < 0)
863*4882a593Smuzhiyun 		goto error_pm_disable;
864*4882a593Smuzhiyun 
865*4882a593Smuzhiyun 	pm_runtime_mark_last_busy(&client->dev);
866*4882a593Smuzhiyun 	pm_runtime_put_autosuspend(&client->dev);
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun 	return 0;
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun error_pm_disable:
871*4882a593Smuzhiyun 	pm_runtime_disable(&client->dev);
872*4882a593Smuzhiyun 	pm_runtime_set_suspended(&client->dev);
873*4882a593Smuzhiyun 	pm_runtime_put_noidle(&client->dev);
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun 	if (data->chip->set_power)
876*4882a593Smuzhiyun 		data->chip->set_power(data, false);
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun error_unregister_device:
879*4882a593Smuzhiyun 	v4l2_device_unregister(v4l2_dev);
880*4882a593Smuzhiyun 	mutex_destroy(&data->lock);
881*4882a593Smuzhiyun 	mutex_destroy(&data->queue_lock);
882*4882a593Smuzhiyun 
883*4882a593Smuzhiyun error_regmap_exit:
884*4882a593Smuzhiyun 	regmap_exit(data->regmap);
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun error_free_device:
887*4882a593Smuzhiyun 	kfree(data);
888*4882a593Smuzhiyun 
889*4882a593Smuzhiyun 	return ret;
890*4882a593Smuzhiyun }
891*4882a593Smuzhiyun 
video_i2c_remove(struct i2c_client * client)892*4882a593Smuzhiyun static int video_i2c_remove(struct i2c_client *client)
893*4882a593Smuzhiyun {
894*4882a593Smuzhiyun 	struct video_i2c_data *data = i2c_get_clientdata(client);
895*4882a593Smuzhiyun 
896*4882a593Smuzhiyun 	pm_runtime_get_sync(&client->dev);
897*4882a593Smuzhiyun 	pm_runtime_disable(&client->dev);
898*4882a593Smuzhiyun 	pm_runtime_set_suspended(&client->dev);
899*4882a593Smuzhiyun 	pm_runtime_put_noidle(&client->dev);
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun 	if (data->chip->set_power)
902*4882a593Smuzhiyun 		data->chip->set_power(data, false);
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 	video_unregister_device(&data->vdev);
905*4882a593Smuzhiyun 
906*4882a593Smuzhiyun 	return 0;
907*4882a593Smuzhiyun }
908*4882a593Smuzhiyun 
909*4882a593Smuzhiyun #ifdef CONFIG_PM
910*4882a593Smuzhiyun 
video_i2c_pm_runtime_suspend(struct device * dev)911*4882a593Smuzhiyun static int video_i2c_pm_runtime_suspend(struct device *dev)
912*4882a593Smuzhiyun {
913*4882a593Smuzhiyun 	struct video_i2c_data *data = i2c_get_clientdata(to_i2c_client(dev));
914*4882a593Smuzhiyun 
915*4882a593Smuzhiyun 	if (!data->chip->set_power)
916*4882a593Smuzhiyun 		return 0;
917*4882a593Smuzhiyun 
918*4882a593Smuzhiyun 	return data->chip->set_power(data, false);
919*4882a593Smuzhiyun }
920*4882a593Smuzhiyun 
video_i2c_pm_runtime_resume(struct device * dev)921*4882a593Smuzhiyun static int video_i2c_pm_runtime_resume(struct device *dev)
922*4882a593Smuzhiyun {
923*4882a593Smuzhiyun 	struct video_i2c_data *data = i2c_get_clientdata(to_i2c_client(dev));
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun 	if (!data->chip->set_power)
926*4882a593Smuzhiyun 		return 0;
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun 	return data->chip->set_power(data, true);
929*4882a593Smuzhiyun }
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun #endif
932*4882a593Smuzhiyun 
933*4882a593Smuzhiyun static const struct dev_pm_ops video_i2c_pm_ops = {
934*4882a593Smuzhiyun 	SET_RUNTIME_PM_OPS(video_i2c_pm_runtime_suspend,
935*4882a593Smuzhiyun 			   video_i2c_pm_runtime_resume, NULL)
936*4882a593Smuzhiyun };
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun static const struct i2c_device_id video_i2c_id_table[] = {
939*4882a593Smuzhiyun 	{ "amg88xx", AMG88XX },
940*4882a593Smuzhiyun 	{ "mlx90640", MLX90640 },
941*4882a593Smuzhiyun 	{}
942*4882a593Smuzhiyun };
943*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, video_i2c_id_table);
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun static const struct of_device_id video_i2c_of_match[] = {
946*4882a593Smuzhiyun 	{ .compatible = "panasonic,amg88xx", .data = &video_i2c_chip[AMG88XX] },
947*4882a593Smuzhiyun 	{ .compatible = "melexis,mlx90640", .data = &video_i2c_chip[MLX90640] },
948*4882a593Smuzhiyun 	{}
949*4882a593Smuzhiyun };
950*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, video_i2c_of_match);
951*4882a593Smuzhiyun 
952*4882a593Smuzhiyun static struct i2c_driver video_i2c_driver = {
953*4882a593Smuzhiyun 	.driver = {
954*4882a593Smuzhiyun 		.name	= VIDEO_I2C_DRIVER,
955*4882a593Smuzhiyun 		.of_match_table = video_i2c_of_match,
956*4882a593Smuzhiyun 		.pm	= &video_i2c_pm_ops,
957*4882a593Smuzhiyun 	},
958*4882a593Smuzhiyun 	.probe		= video_i2c_probe,
959*4882a593Smuzhiyun 	.remove		= video_i2c_remove,
960*4882a593Smuzhiyun 	.id_table	= video_i2c_id_table,
961*4882a593Smuzhiyun };
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun module_i2c_driver(video_i2c_driver);
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
966*4882a593Smuzhiyun MODULE_DESCRIPTION("I2C transport video support");
967*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
968