hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/media/i2c/video-i2c.c
....@@ -6,6 +6,7 @@
66 *
77 * Supported:
88 * - Panasonic AMG88xx Grid-Eye Sensors
9
+ * - Melexis MLX90640 Thermal Cameras
910 */
1011
1112 #include <linux/delay.h>
....@@ -17,6 +18,9 @@
1718 #include <linux/module.h>
1819 #include <linux/mutex.h>
1920 #include <linux/of_device.h>
21
+#include <linux/pm_runtime.h>
22
+#include <linux/nvmem-provider.h>
23
+#include <linux/regmap.h>
2024 #include <linux/sched.h>
2125 #include <linux/slab.h>
2226 #include <linux/videodev2.h>
....@@ -38,7 +42,7 @@
3842 };
3943
4044 struct video_i2c_data {
41
- struct i2c_client *client;
45
+ struct regmap *regmap;
4246 const struct video_i2c_chip *chip;
4347 struct mutex lock;
4448 spinlock_t slock;
....@@ -51,6 +55,8 @@
5155
5256 struct task_struct *kthread_vid_cap;
5357 struct list_head vid_cap_active;
58
+
59
+ struct v4l2_fract frame_interval;
5460 };
5561
5662 static const struct v4l2_fmtdesc amg88xx_format = {
....@@ -62,13 +68,34 @@
6268 .height = 8,
6369 };
6470
71
+static const struct v4l2_fmtdesc mlx90640_format = {
72
+ .pixelformat = V4L2_PIX_FMT_Y16_BE,
73
+};
74
+
75
+static const struct v4l2_frmsize_discrete mlx90640_size = {
76
+ .width = 32,
77
+ .height = 26, /* 24 lines of pixel data + 2 lines of processing data */
78
+};
79
+
80
+static const struct regmap_config amg88xx_regmap_config = {
81
+ .reg_bits = 8,
82
+ .val_bits = 8,
83
+ .max_register = 0xff
84
+};
85
+
86
+static const struct regmap_config mlx90640_regmap_config = {
87
+ .reg_bits = 16,
88
+ .val_bits = 16,
89
+};
90
+
6591 struct video_i2c_chip {
6692 /* video dimensions */
6793 const struct v4l2_fmtdesc *format;
6894 const struct v4l2_frmsize_discrete *size;
6995
70
- /* max frames per second */
71
- unsigned int max_fps;
96
+ /* available frame intervals */
97
+ const struct v4l2_fract *frame_intervals;
98
+ unsigned int num_frame_intervals;
7299
73100 /* pixel buffer size */
74101 unsigned int buffer_size;
....@@ -76,33 +103,156 @@
76103 /* pixel size in bits */
77104 unsigned int bpp;
78105
106
+ const struct regmap_config *regmap_config;
107
+ struct nvmem_config *nvmem_config;
108
+
109
+ /* setup function */
110
+ int (*setup)(struct video_i2c_data *data);
111
+
79112 /* xfer function */
80113 int (*xfer)(struct video_i2c_data *data, char *buf);
114
+
115
+ /* power control function */
116
+ int (*set_power)(struct video_i2c_data *data, bool on);
81117
82118 /* hwmon init function */
83119 int (*hwmon_init)(struct video_i2c_data *data);
84120 };
85121
122
+static int mlx90640_nvram_read(void *priv, unsigned int offset, void *val,
123
+ size_t bytes)
124
+{
125
+ struct video_i2c_data *data = priv;
126
+
127
+ return regmap_bulk_read(data->regmap, 0x2400 + offset, val, bytes);
128
+}
129
+
130
+static struct nvmem_config mlx90640_nvram_config = {
131
+ .name = "mlx90640_nvram",
132
+ .word_size = 2,
133
+ .stride = 1,
134
+ .size = 1664,
135
+ .reg_read = mlx90640_nvram_read,
136
+};
137
+
138
+/* Power control register */
139
+#define AMG88XX_REG_PCTL 0x00
140
+#define AMG88XX_PCTL_NORMAL 0x00
141
+#define AMG88XX_PCTL_SLEEP 0x10
142
+
143
+/* Reset register */
144
+#define AMG88XX_REG_RST 0x01
145
+#define AMG88XX_RST_FLAG 0x30
146
+#define AMG88XX_RST_INIT 0x3f
147
+
148
+/* Frame rate register */
149
+#define AMG88XX_REG_FPSC 0x02
150
+#define AMG88XX_FPSC_1FPS BIT(0)
151
+
152
+/* Thermistor register */
153
+#define AMG88XX_REG_TTHL 0x0e
154
+
155
+/* Temperature register */
156
+#define AMG88XX_REG_T01L 0x80
157
+
158
+/* Control register */
159
+#define MLX90640_REG_CTL1 0x800d
160
+#define MLX90640_REG_CTL1_MASK 0x0380
161
+#define MLX90640_REG_CTL1_MASK_SHIFT 7
162
+
86163 static int amg88xx_xfer(struct video_i2c_data *data, char *buf)
87164 {
88
- struct i2c_client *client = data->client;
89
- struct i2c_msg msg[2];
90
- u8 reg = 0x80;
165
+ return regmap_bulk_read(data->regmap, AMG88XX_REG_T01L, buf,
166
+ data->chip->buffer_size);
167
+}
168
+
169
+static int mlx90640_xfer(struct video_i2c_data *data, char *buf)
170
+{
171
+ return regmap_bulk_read(data->regmap, 0x400, buf,
172
+ data->chip->buffer_size);
173
+}
174
+
175
+static int amg88xx_setup(struct video_i2c_data *data)
176
+{
177
+ unsigned int mask = AMG88XX_FPSC_1FPS;
178
+ unsigned int val;
179
+
180
+ if (data->frame_interval.numerator == data->frame_interval.denominator)
181
+ val = mask;
182
+ else
183
+ val = 0;
184
+
185
+ return regmap_update_bits(data->regmap, AMG88XX_REG_FPSC, mask, val);
186
+}
187
+
188
+static int mlx90640_setup(struct video_i2c_data *data)
189
+{
190
+ unsigned int n, idx;
191
+
192
+ for (n = 0; n < data->chip->num_frame_intervals - 1; n++) {
193
+ if (V4L2_FRACT_COMPARE(data->frame_interval, ==,
194
+ data->chip->frame_intervals[n]))
195
+ break;
196
+ }
197
+
198
+ idx = data->chip->num_frame_intervals - n - 1;
199
+
200
+ return regmap_update_bits(data->regmap, MLX90640_REG_CTL1,
201
+ MLX90640_REG_CTL1_MASK,
202
+ idx << MLX90640_REG_CTL1_MASK_SHIFT);
203
+}
204
+
205
+static int amg88xx_set_power_on(struct video_i2c_data *data)
206
+{
91207 int ret;
92208
93
- msg[0].addr = client->addr;
94
- msg[0].flags = 0;
95
- msg[0].len = 1;
96
- msg[0].buf = (char *)&reg;
209
+ ret = regmap_write(data->regmap, AMG88XX_REG_PCTL, AMG88XX_PCTL_NORMAL);
210
+ if (ret)
211
+ return ret;
97212
98
- msg[1].addr = client->addr;
99
- msg[1].flags = I2C_M_RD;
100
- msg[1].len = data->chip->buffer_size;
101
- msg[1].buf = (char *)buf;
213
+ msleep(50);
102214
103
- ret = i2c_transfer(client->adapter, msg, 2);
215
+ ret = regmap_write(data->regmap, AMG88XX_REG_RST, AMG88XX_RST_INIT);
216
+ if (ret)
217
+ return ret;
104218
105
- return (ret == 2) ? 0 : -EIO;
219
+ usleep_range(2000, 3000);
220
+
221
+ ret = regmap_write(data->regmap, AMG88XX_REG_RST, AMG88XX_RST_FLAG);
222
+ if (ret)
223
+ return ret;
224
+
225
+ /*
226
+ * Wait two frames before reading thermistor and temperature registers
227
+ */
228
+ msleep(200);
229
+
230
+ return 0;
231
+}
232
+
233
+static int amg88xx_set_power_off(struct video_i2c_data *data)
234
+{
235
+ int ret;
236
+
237
+ ret = regmap_write(data->regmap, AMG88XX_REG_PCTL, AMG88XX_PCTL_SLEEP);
238
+ if (ret)
239
+ return ret;
240
+ /*
241
+ * Wait for a while to avoid resuming normal mode immediately after
242
+ * entering sleep mode, otherwise the device occasionally goes wrong
243
+ * (thermistor and temperature registers are not updated at all)
244
+ */
245
+ msleep(100);
246
+
247
+ return 0;
248
+}
249
+
250
+static int amg88xx_set_power(struct video_i2c_data *data, bool on)
251
+{
252
+ if (on)
253
+ return amg88xx_set_power_on(data);
254
+
255
+ return amg88xx_set_power_off(data);
106256 }
107257
108258 #if IS_REACHABLE(CONFIG_HWMON)
....@@ -133,11 +283,22 @@
133283 u32 attr, int channel, long *val)
134284 {
135285 struct video_i2c_data *data = dev_get_drvdata(dev);
136
- struct i2c_client *client = data->client;
137
- int tmp = i2c_smbus_read_word_data(client, 0x0e);
286
+ __le16 buf;
287
+ int tmp;
138288
139
- if (tmp < 0)
289
+ tmp = pm_runtime_get_sync(regmap_get_device(data->regmap));
290
+ if (tmp < 0) {
291
+ pm_runtime_put_noidle(regmap_get_device(data->regmap));
140292 return tmp;
293
+ }
294
+
295
+ tmp = regmap_bulk_read(data->regmap, AMG88XX_REG_TTHL, &buf, 2);
296
+ pm_runtime_mark_last_busy(regmap_get_device(data->regmap));
297
+ pm_runtime_put_autosuspend(regmap_get_device(data->regmap));
298
+ if (tmp)
299
+ return tmp;
300
+
301
+ tmp = le16_to_cpu(buf);
141302
142303 /*
143304 * Check for sign bit, this isn't a two's complement value but an
....@@ -164,8 +325,9 @@
164325
165326 static int amg88xx_hwmon_init(struct video_i2c_data *data)
166327 {
167
- void *hwmon = devm_hwmon_device_register_with_info(&data->client->dev,
168
- "amg88xx", data, &amg88xx_chip_info, NULL);
328
+ struct device *dev = regmap_get_device(data->regmap);
329
+ void *hwmon = devm_hwmon_device_register_with_info(dev, "amg88xx", data,
330
+ &amg88xx_chip_info, NULL);
169331
170332 return PTR_ERR_OR_ZERO(hwmon);
171333 }
....@@ -173,17 +335,52 @@
173335 #define amg88xx_hwmon_init NULL
174336 #endif
175337
176
-#define AMG88XX 0
338
+enum {
339
+ AMG88XX,
340
+ MLX90640,
341
+};
342
+
343
+static const struct v4l2_fract amg88xx_frame_intervals[] = {
344
+ { 1, 10 },
345
+ { 1, 1 },
346
+};
347
+
348
+static const struct v4l2_fract mlx90640_frame_intervals[] = {
349
+ { 1, 64 },
350
+ { 1, 32 },
351
+ { 1, 16 },
352
+ { 1, 8 },
353
+ { 1, 4 },
354
+ { 1, 2 },
355
+ { 1, 1 },
356
+ { 2, 1 },
357
+};
177358
178359 static const struct video_i2c_chip video_i2c_chip[] = {
179360 [AMG88XX] = {
180361 .size = &amg88xx_size,
181362 .format = &amg88xx_format,
182
- .max_fps = 10,
363
+ .frame_intervals = amg88xx_frame_intervals,
364
+ .num_frame_intervals = ARRAY_SIZE(amg88xx_frame_intervals),
183365 .buffer_size = 128,
184366 .bpp = 16,
367
+ .regmap_config = &amg88xx_regmap_config,
368
+ .setup = &amg88xx_setup,
185369 .xfer = &amg88xx_xfer,
370
+ .set_power = amg88xx_set_power,
186371 .hwmon_init = amg88xx_hwmon_init,
372
+ },
373
+ [MLX90640] = {
374
+ .size = &mlx90640_size,
375
+ .format = &mlx90640_format,
376
+ .frame_intervals = mlx90640_frame_intervals,
377
+ .num_frame_intervals = ARRAY_SIZE(mlx90640_frame_intervals),
378
+ .buffer_size = 1664,
379
+ .bpp = 16,
380
+ .regmap_config = &mlx90640_regmap_config,
381
+ .nvmem_config = &mlx90640_nvram_config,
382
+ .setup = mlx90640_setup,
383
+ .xfer = mlx90640_xfer,
187384 },
188385 };
189386
....@@ -246,7 +443,8 @@
246443 static int video_i2c_thread_vid_cap(void *priv)
247444 {
248445 struct video_i2c_data *data = priv;
249
- unsigned int delay = msecs_to_jiffies(1000 / data->chip->max_fps);
446
+ unsigned int delay = mult_frac(HZ, data->frame_interval.numerator,
447
+ data->frame_interval.denominator);
250448
251449 set_freezable();
252450
....@@ -308,19 +506,36 @@
308506 static int start_streaming(struct vb2_queue *vq, unsigned int count)
309507 {
310508 struct video_i2c_data *data = vb2_get_drv_priv(vq);
509
+ struct device *dev = regmap_get_device(data->regmap);
510
+ int ret;
311511
312512 if (data->kthread_vid_cap)
313513 return 0;
314514
515
+ ret = pm_runtime_get_sync(dev);
516
+ if (ret < 0) {
517
+ pm_runtime_put_noidle(dev);
518
+ goto error_del_list;
519
+ }
520
+
521
+ ret = data->chip->setup(data);
522
+ if (ret)
523
+ goto error_rpm_put;
524
+
315525 data->sequence = 0;
316526 data->kthread_vid_cap = kthread_run(video_i2c_thread_vid_cap, data,
317527 "%s-vid-cap", data->v4l2_dev.name);
318
- if (!IS_ERR(data->kthread_vid_cap))
528
+ ret = PTR_ERR_OR_ZERO(data->kthread_vid_cap);
529
+ if (!ret)
319530 return 0;
320531
532
+error_rpm_put:
533
+ pm_runtime_mark_last_busy(dev);
534
+ pm_runtime_put_autosuspend(dev);
535
+error_del_list:
321536 video_i2c_del_list(vq, VB2_BUF_STATE_QUEUED);
322537
323
- return PTR_ERR(data->kthread_vid_cap);
538
+ return ret;
324539 }
325540
326541 static void stop_streaming(struct vb2_queue *vq)
....@@ -332,11 +547,13 @@
332547
333548 kthread_stop(data->kthread_vid_cap);
334549 data->kthread_vid_cap = NULL;
550
+ pm_runtime_mark_last_busy(regmap_get_device(data->regmap));
551
+ pm_runtime_put_autosuspend(regmap_get_device(data->regmap));
335552
336553 video_i2c_del_list(vq, VB2_BUF_STATE_ERROR);
337554 }
338555
339
-static struct vb2_ops video_i2c_video_qops = {
556
+static const struct vb2_ops video_i2c_video_qops = {
340557 .queue_setup = queue_setup,
341558 .buf_prepare = buffer_prepare,
342559 .buf_queue = buffer_queue,
....@@ -350,10 +567,11 @@
350567 struct v4l2_capability *vcap)
351568 {
352569 struct video_i2c_data *data = video_drvdata(file);
353
- struct i2c_client *client = data->client;
570
+ struct device *dev = regmap_get_device(data->regmap);
571
+ struct i2c_client *client = to_i2c_client(dev);
354572
355
- strlcpy(vcap->driver, data->v4l2_dev.name, sizeof(vcap->driver));
356
- strlcpy(vcap->card, data->vdev.name, sizeof(vcap->card));
573
+ strscpy(vcap->driver, data->v4l2_dev.name, sizeof(vcap->driver));
574
+ strscpy(vcap->card, data->vdev.name, sizeof(vcap->card));
357575
358576 sprintf(vcap->bus_info, "I2C:%d-%d", client->adapter->nr, client->addr);
359577
....@@ -378,7 +596,7 @@
378596 if (vin->index > 0)
379597 return -EINVAL;
380598
381
- strlcpy(vin->name, "Camera", sizeof(vin->name));
599
+ strscpy(vin->name, "Camera", sizeof(vin->name));
382600
383601 vin->type = V4L2_INPUT_TYPE_CAMERA;
384602
....@@ -426,15 +644,14 @@
426644 const struct video_i2c_data *data = video_drvdata(file);
427645 const struct v4l2_frmsize_discrete *size = data->chip->size;
428646
429
- if (fe->index > 0)
647
+ if (fe->index >= data->chip->num_frame_intervals)
430648 return -EINVAL;
431649
432650 if (fe->width != size->width || fe->height != size->height)
433651 return -EINVAL;
434652
435653 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
436
- fe->discrete.numerator = 1;
437
- fe->discrete.denominator = data->chip->max_fps;
654
+ fe->discrete = data->chip->frame_intervals[fe->index];
438655
439656 return 0;
440657 }
....@@ -479,10 +696,25 @@
479696
480697 parm->parm.capture.readbuffers = 1;
481698 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
482
- parm->parm.capture.timeperframe.numerator = 1;
483
- parm->parm.capture.timeperframe.denominator = data->chip->max_fps;
699
+ parm->parm.capture.timeperframe = data->frame_interval;
484700
485701 return 0;
702
+}
703
+
704
+static int video_i2c_s_parm(struct file *filp, void *priv,
705
+ struct v4l2_streamparm *parm)
706
+{
707
+ struct video_i2c_data *data = video_drvdata(filp);
708
+ int i;
709
+
710
+ for (i = 0; i < data->chip->num_frame_intervals - 1; i++) {
711
+ if (V4L2_FRACT_COMPARE(parm->parm.capture.timeperframe, <=,
712
+ data->chip->frame_intervals[i]))
713
+ break;
714
+ }
715
+ data->frame_interval = data->chip->frame_intervals[i];
716
+
717
+ return video_i2c_g_parm(filp, priv, parm);
486718 }
487719
488720 static const struct v4l2_ioctl_ops video_i2c_ioctl_ops = {
....@@ -496,7 +728,7 @@
496728 .vidioc_g_fmt_vid_cap = video_i2c_try_fmt_vid_cap,
497729 .vidioc_s_fmt_vid_cap = video_i2c_s_fmt_vid_cap,
498730 .vidioc_g_parm = video_i2c_g_parm,
499
- .vidioc_s_parm = video_i2c_g_parm,
731
+ .vidioc_s_parm = video_i2c_s_parm,
500732 .vidioc_try_fmt_vid_cap = video_i2c_try_fmt_vid_cap,
501733 .vidioc_reqbufs = vb2_ioctl_reqbufs,
502734 .vidioc_create_bufs = vb2_ioctl_create_bufs,
....@@ -515,6 +747,7 @@
515747 v4l2_device_unregister(&data->v4l2_dev);
516748 mutex_destroy(&data->lock);
517749 mutex_destroy(&data->queue_lock);
750
+ regmap_exit(data->regmap);
518751 kfree(data);
519752 }
520753
....@@ -537,13 +770,18 @@
537770 else
538771 goto error_free_device;
539772
540
- data->client = client;
773
+ data->regmap = regmap_init_i2c(client, data->chip->regmap_config);
774
+ if (IS_ERR(data->regmap)) {
775
+ ret = PTR_ERR(data->regmap);
776
+ goto error_free_device;
777
+ }
778
+
541779 v4l2_dev = &data->v4l2_dev;
542
- strlcpy(v4l2_dev->name, VIDEO_I2C_DRIVER, sizeof(v4l2_dev->name));
780
+ strscpy(v4l2_dev->name, VIDEO_I2C_DRIVER, sizeof(v4l2_dev->name));
543781
544782 ret = v4l2_device_register(&client->dev, v4l2_dev);
545783 if (ret < 0)
546
- goto error_free_device;
784
+ goto error_regmap_exit;
547785
548786 mutex_init(&data->lock);
549787 mutex_init(&data->queue_lock);
....@@ -580,8 +818,22 @@
580818 spin_lock_init(&data->slock);
581819 INIT_LIST_HEAD(&data->vid_cap_active);
582820
821
+ data->frame_interval = data->chip->frame_intervals[0];
822
+
583823 video_set_drvdata(&data->vdev, data);
584824 i2c_set_clientdata(client, data);
825
+
826
+ if (data->chip->set_power) {
827
+ ret = data->chip->set_power(data, true);
828
+ if (ret)
829
+ goto error_unregister_device;
830
+ }
831
+
832
+ pm_runtime_get_noresume(&client->dev);
833
+ pm_runtime_set_active(&client->dev);
834
+ pm_runtime_enable(&client->dev);
835
+ pm_runtime_set_autosuspend_delay(&client->dev, 2000);
836
+ pm_runtime_use_autosuspend(&client->dev);
585837
586838 if (data->chip->hwmon_init) {
587839 ret = data->chip->hwmon_init(data);
....@@ -591,16 +843,45 @@
591843 }
592844 }
593845
594
- ret = video_register_device(&data->vdev, VFL_TYPE_GRABBER, -1);
846
+ if (data->chip->nvmem_config) {
847
+ struct nvmem_config *config = data->chip->nvmem_config;
848
+ struct nvmem_device *device;
849
+
850
+ config->priv = data;
851
+ config->dev = &client->dev;
852
+
853
+ device = devm_nvmem_register(&client->dev, config);
854
+
855
+ if (IS_ERR(device)) {
856
+ dev_warn(&client->dev,
857
+ "failed to register nvmem device\n");
858
+ }
859
+ }
860
+
861
+ ret = video_register_device(&data->vdev, VFL_TYPE_VIDEO, -1);
595862 if (ret < 0)
596
- goto error_unregister_device;
863
+ goto error_pm_disable;
864
+
865
+ pm_runtime_mark_last_busy(&client->dev);
866
+ pm_runtime_put_autosuspend(&client->dev);
597867
598868 return 0;
869
+
870
+error_pm_disable:
871
+ pm_runtime_disable(&client->dev);
872
+ pm_runtime_set_suspended(&client->dev);
873
+ pm_runtime_put_noidle(&client->dev);
874
+
875
+ if (data->chip->set_power)
876
+ data->chip->set_power(data, false);
599877
600878 error_unregister_device:
601879 v4l2_device_unregister(v4l2_dev);
602880 mutex_destroy(&data->lock);
603881 mutex_destroy(&data->queue_lock);
882
+
883
+error_regmap_exit:
884
+ regmap_exit(data->regmap);
604885
605886 error_free_device:
606887 kfree(data);
....@@ -612,19 +893,58 @@
612893 {
613894 struct video_i2c_data *data = i2c_get_clientdata(client);
614895
896
+ pm_runtime_get_sync(&client->dev);
897
+ pm_runtime_disable(&client->dev);
898
+ pm_runtime_set_suspended(&client->dev);
899
+ pm_runtime_put_noidle(&client->dev);
900
+
901
+ if (data->chip->set_power)
902
+ data->chip->set_power(data, false);
903
+
615904 video_unregister_device(&data->vdev);
616905
617906 return 0;
618907 }
619908
909
+#ifdef CONFIG_PM
910
+
911
+static int video_i2c_pm_runtime_suspend(struct device *dev)
912
+{
913
+ struct video_i2c_data *data = i2c_get_clientdata(to_i2c_client(dev));
914
+
915
+ if (!data->chip->set_power)
916
+ return 0;
917
+
918
+ return data->chip->set_power(data, false);
919
+}
920
+
921
+static int video_i2c_pm_runtime_resume(struct device *dev)
922
+{
923
+ struct video_i2c_data *data = i2c_get_clientdata(to_i2c_client(dev));
924
+
925
+ if (!data->chip->set_power)
926
+ return 0;
927
+
928
+ return data->chip->set_power(data, true);
929
+}
930
+
931
+#endif
932
+
933
+static const struct dev_pm_ops video_i2c_pm_ops = {
934
+ SET_RUNTIME_PM_OPS(video_i2c_pm_runtime_suspend,
935
+ video_i2c_pm_runtime_resume, NULL)
936
+};
937
+
620938 static const struct i2c_device_id video_i2c_id_table[] = {
621939 { "amg88xx", AMG88XX },
940
+ { "mlx90640", MLX90640 },
622941 {}
623942 };
624943 MODULE_DEVICE_TABLE(i2c, video_i2c_id_table);
625944
626945 static const struct of_device_id video_i2c_of_match[] = {
627946 { .compatible = "panasonic,amg88xx", .data = &video_i2c_chip[AMG88XX] },
947
+ { .compatible = "melexis,mlx90640", .data = &video_i2c_chip[MLX90640] },
628948 {}
629949 };
630950 MODULE_DEVICE_TABLE(of, video_i2c_of_match);
....@@ -633,6 +953,7 @@
633953 .driver = {
634954 .name = VIDEO_I2C_DRIVER,
635955 .of_match_table = video_i2c_of_match,
956
+ .pm = &video_i2c_pm_ops,
636957 },
637958 .probe = video_i2c_probe,
638959 .remove = video_i2c_remove,