GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / hwmon / mr75203.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020 MaxLinear, Inc.
4  *
5  * This driver is a hardware monitoring driver for PVT controller
6  * (MR75203) which is used to configure & control Moortec embedded
7  * analog IP to enable multiple embedded temperature sensor(TS),
8  * voltage monitor(VM) & process detector(PD) modules.
9  */
10 #include <linux/bits.h>
11 #include <linux/clk.h>
12 #include <linux/hwmon.h>
13 #include <linux/module.h>
14 #include <linux/mod_devicetable.h>
15 #include <linux/mutex.h>
16 #include <linux/platform_device.h>
17 #include <linux/property.h>
18 #include <linux/regmap.h>
19 #include <linux/reset.h>
20
21 /* PVT Common register */
22 #define PVT_IP_CONFIG   0x04
23 #define TS_NUM_MSK      GENMASK(4, 0)
24 #define TS_NUM_SFT      0
25 #define PD_NUM_MSK      GENMASK(12, 8)
26 #define PD_NUM_SFT      8
27 #define VM_NUM_MSK      GENMASK(20, 16)
28 #define VM_NUM_SFT      16
29 #define CH_NUM_MSK      GENMASK(31, 24)
30 #define CH_NUM_SFT      24
31
32 /* Macro Common Register */
33 #define CLK_SYNTH               0x00
34 #define CLK_SYNTH_LO_SFT        0
35 #define CLK_SYNTH_HI_SFT        8
36 #define CLK_SYNTH_HOLD_SFT      16
37 #define CLK_SYNTH_EN            BIT(24)
38 #define CLK_SYS_CYCLES_MAX      514
39 #define CLK_SYS_CYCLES_MIN      2
40 #define HZ_PER_MHZ              1000000L
41
42 #define SDIF_DISABLE    0x04
43
44 #define SDIF_STAT       0x08
45 #define SDIF_BUSY       BIT(0)
46 #define SDIF_LOCK       BIT(1)
47
48 #define SDIF_W          0x0c
49 #define SDIF_PROG       BIT(31)
50 #define SDIF_WRN_W      BIT(27)
51 #define SDIF_WRN_R      0x00
52 #define SDIF_ADDR_SFT   24
53
54 #define SDIF_HALT       0x10
55 #define SDIF_CTRL       0x14
56 #define SDIF_SMPL_CTRL  0x20
57
58 /* TS & PD Individual Macro Register */
59 #define COM_REG_SIZE    0x40
60
61 #define SDIF_DONE(n)    (COM_REG_SIZE + 0x14 + 0x40 * (n))
62 #define SDIF_SMPL_DONE  BIT(0)
63
64 #define SDIF_DATA(n)    (COM_REG_SIZE + 0x18 + 0x40 * (n))
65 #define SAMPLE_DATA_MSK GENMASK(15, 0)
66
67 #define HILO_RESET(n)   (COM_REG_SIZE + 0x2c + 0x40 * (n))
68
69 /* VM Individual Macro Register */
70 #define VM_COM_REG_SIZE 0x200
71 #define VM_SDIF_DONE(vm)        (VM_COM_REG_SIZE + 0x34 + 0x200 * (vm))
72 #define VM_SDIF_DATA(vm, ch)    \
73         (VM_COM_REG_SIZE + 0x40 + 0x200 * (vm) + 0x4 * (ch))
74
75 /* SDA Slave Register */
76 #define IP_CTRL                 0x00
77 #define IP_RST_REL              BIT(1)
78 #define IP_RUN_CONT             BIT(3)
79 #define IP_AUTO                 BIT(8)
80 #define IP_VM_MODE              BIT(10)
81
82 #define IP_CFG                  0x01
83 #define CFG0_MODE_2             BIT(0)
84 #define CFG0_PARALLEL_OUT       0
85 #define CFG0_12_BIT             0
86 #define CFG1_VOL_MEAS_MODE      0
87 #define CFG1_PARALLEL_OUT       0
88 #define CFG1_14_BIT             0
89
90 #define IP_DATA         0x03
91
92 #define IP_POLL         0x04
93 #define VM_CH_INIT      BIT(20)
94 #define VM_CH_REQ       BIT(21)
95
96 #define IP_TMR                  0x05
97 #define POWER_DELAY_CYCLE_256   0x100
98 #define POWER_DELAY_CYCLE_64    0x40
99
100 #define PVT_POLL_DELAY_US       20
101 #define PVT_POLL_TIMEOUT_US     20000
102 #define PVT_H_CONST             100000
103 #define PVT_CAL5_CONST          2047
104 #define PVT_G_CONST             40000
105 #define PVT_CONV_BITS           10
106 #define PVT_N_CONST             90
107 #define PVT_R_CONST             245805
108
109 struct pvt_device {
110         struct regmap           *c_map;
111         struct regmap           *t_map;
112         struct regmap           *p_map;
113         struct regmap           *v_map;
114         struct clk              *clk;
115         struct reset_control    *rst;
116         u32                     t_num;
117         u32                     p_num;
118         u32                     v_num;
119         u32                     c_num;
120         u32                     ip_freq;
121         u8                      *vm_idx;
122 };
123
124 static umode_t pvt_is_visible(const void *data, enum hwmon_sensor_types type,
125                               u32 attr, int channel)
126 {
127         switch (type) {
128         case hwmon_temp:
129                 if (attr == hwmon_temp_input)
130                         return 0444;
131                 break;
132         case hwmon_in:
133                 if (attr == hwmon_in_input)
134                         return 0444;
135                 break;
136         default:
137                 break;
138         }
139         return 0;
140 }
141
142 static int pvt_read_temp(struct device *dev, u32 attr, int channel, long *val)
143 {
144         struct pvt_device *pvt = dev_get_drvdata(dev);
145         struct regmap *t_map = pvt->t_map;
146         u32 stat, nbs;
147         int ret;
148         u64 tmp;
149
150         switch (attr) {
151         case hwmon_temp_input:
152                 ret = regmap_read_poll_timeout(t_map, SDIF_DONE(channel),
153                                                stat, stat & SDIF_SMPL_DONE,
154                                                PVT_POLL_DELAY_US,
155                                                PVT_POLL_TIMEOUT_US);
156                 if (ret)
157                         return ret;
158
159                 ret = regmap_read(t_map, SDIF_DATA(channel), &nbs);
160                 if(ret < 0)
161                         return ret;
162
163                 nbs &= SAMPLE_DATA_MSK;
164
165                 /*
166                  * Convert the register value to
167                  * degrees centigrade temperature
168                  */
169                 tmp = nbs * PVT_H_CONST;
170                 do_div(tmp, PVT_CAL5_CONST);
171                 *val = tmp - PVT_G_CONST - pvt->ip_freq;
172
173                 return 0;
174         default:
175                 return -EOPNOTSUPP;
176         }
177 }
178
179 static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
180 {
181         struct pvt_device *pvt = dev_get_drvdata(dev);
182         struct regmap *v_map = pvt->v_map;
183         u8 vm_idx, ch_idx;
184         u32 n, stat;
185         int ret;
186
187         if (channel >= pvt->v_num * pvt->c_num)
188                 return -EINVAL;
189
190         vm_idx = pvt->vm_idx[channel / pvt->c_num];
191         ch_idx = channel % pvt->c_num;
192
193         switch (attr) {
194         case hwmon_in_input:
195                 ret = regmap_read_poll_timeout(v_map, VM_SDIF_DONE(vm_idx),
196                                                stat, stat & SDIF_SMPL_DONE,
197                                                PVT_POLL_DELAY_US,
198                                                PVT_POLL_TIMEOUT_US);
199                 if (ret)
200                         return ret;
201
202                 ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx, ch_idx), &n);
203                 if(ret < 0)
204                         return ret;
205
206                 n &= SAMPLE_DATA_MSK;
207                 /*
208                  * Convert the N bitstream count into voltage.
209                  * To support negative voltage calculation for 64bit machines
210                  * n must be cast to long, since n and *val differ both in
211                  * signedness and in size.
212                  * Division is used instead of right shift, because for signed
213                  * numbers, the sign bit is used to fill the vacated bit
214                  * positions, and if the number is negative, 1 is used.
215                  * BIT(x) may not be used instead of (1 << x) because it's
216                  * unsigned.
217                  */
218                 *val = (PVT_N_CONST * (long)n - PVT_R_CONST) / (1 << PVT_CONV_BITS);
219
220                 return 0;
221         default:
222                 return -EOPNOTSUPP;
223         }
224 }
225
226 static int pvt_read(struct device *dev, enum hwmon_sensor_types type,
227                     u32 attr, int channel, long *val)
228 {
229         switch (type) {
230         case hwmon_temp:
231                 return pvt_read_temp(dev, attr, channel, val);
232         case hwmon_in:
233                 return pvt_read_in(dev, attr, channel, val);
234         default:
235                 return -EOPNOTSUPP;
236         }
237 }
238
239 static const u32 pvt_chip_config[] = {
240         HWMON_C_REGISTER_TZ,
241         0
242 };
243
244 static const struct hwmon_channel_info pvt_chip = {
245         .type = hwmon_chip,
246         .config = pvt_chip_config,
247 };
248
249 static struct hwmon_channel_info pvt_temp = {
250         .type = hwmon_temp,
251 };
252
253 static struct hwmon_channel_info pvt_in = {
254         .type = hwmon_in,
255 };
256
257 static const struct hwmon_ops pvt_hwmon_ops = {
258         .is_visible = pvt_is_visible,
259         .read = pvt_read,
260 };
261
262 static struct hwmon_chip_info pvt_chip_info = {
263         .ops = &pvt_hwmon_ops,
264 };
265
266 static int pvt_init(struct pvt_device *pvt)
267 {
268         u16 sys_freq, key, middle, low = 4, high = 8;
269         struct regmap *t_map = pvt->t_map;
270         struct regmap *p_map = pvt->p_map;
271         struct regmap *v_map = pvt->v_map;
272         u32 t_num = pvt->t_num;
273         u32 p_num = pvt->p_num;
274         u32 v_num = pvt->v_num;
275         u32 clk_synth, val;
276         int ret;
277
278         sys_freq = clk_get_rate(pvt->clk) / HZ_PER_MHZ;
279         while (high >= low) {
280                 middle = (low + high + 1) / 2;
281                 key = DIV_ROUND_CLOSEST(sys_freq, middle);
282                 if (key > CLK_SYS_CYCLES_MAX) {
283                         low = middle + 1;
284                         continue;
285                 } else if (key < CLK_SYS_CYCLES_MIN) {
286                         high = middle - 1;
287                         continue;
288                 } else {
289                         break;
290                 }
291         }
292
293         /*
294          * The system supports 'clk_sys' to 'clk_ip' frequency ratios
295          * from 2:1 to 512:1
296          */
297         key = clamp_val(key, CLK_SYS_CYCLES_MIN, CLK_SYS_CYCLES_MAX) - 2;
298
299         clk_synth = ((key + 1) >> 1) << CLK_SYNTH_LO_SFT |
300                     (key >> 1) << CLK_SYNTH_HI_SFT |
301                     (key >> 1) << CLK_SYNTH_HOLD_SFT | CLK_SYNTH_EN;
302
303         pvt->ip_freq = sys_freq * 100 / (key + 2);
304
305         if (t_num) {
306                 ret = regmap_write(t_map, SDIF_SMPL_CTRL, 0x0);
307                 if(ret < 0)
308                         return ret;
309
310                 ret = regmap_write(t_map, SDIF_HALT, 0x0);
311                 if(ret < 0)
312                         return ret;
313
314                 ret = regmap_write(t_map, CLK_SYNTH, clk_synth);
315                 if(ret < 0)
316                         return ret;
317
318                 ret = regmap_write(t_map, SDIF_DISABLE, 0x0);
319                 if(ret < 0)
320                         return ret;
321
322                 ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
323                                                val, !(val & SDIF_BUSY),
324                                                PVT_POLL_DELAY_US,
325                                                PVT_POLL_TIMEOUT_US);
326                 if (ret)
327                         return ret;
328
329                 val = CFG0_MODE_2 | CFG0_PARALLEL_OUT | CFG0_12_BIT |
330                       IP_CFG << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
331                 ret = regmap_write(t_map, SDIF_W, val);
332                 if(ret < 0)
333                         return ret;
334
335                 ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
336                                                val, !(val & SDIF_BUSY),
337                                                PVT_POLL_DELAY_US,
338                                                PVT_POLL_TIMEOUT_US);
339                 if (ret)
340                         return ret;
341
342                 val = POWER_DELAY_CYCLE_256 | IP_TMR << SDIF_ADDR_SFT |
343                               SDIF_WRN_W | SDIF_PROG;
344                 ret = regmap_write(t_map, SDIF_W, val);
345                 if(ret < 0)
346                         return ret;
347
348                 ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
349                                                val, !(val & SDIF_BUSY),
350                                                PVT_POLL_DELAY_US,
351                                                PVT_POLL_TIMEOUT_US);
352                 if (ret)
353                         return ret;
354
355                 val = IP_RST_REL | IP_RUN_CONT | IP_AUTO |
356                       IP_CTRL << SDIF_ADDR_SFT |
357                       SDIF_WRN_W | SDIF_PROG;
358                 ret = regmap_write(t_map, SDIF_W, val);
359                 if(ret < 0)
360                         return ret;
361         }
362
363         if (p_num) {
364                 ret = regmap_write(p_map, SDIF_HALT, 0x0);
365                 if(ret < 0)
366                         return ret;
367
368                 ret = regmap_write(p_map, SDIF_DISABLE, BIT(p_num) - 1);
369                 if(ret < 0)
370                         return ret;
371
372                 ret = regmap_write(p_map, CLK_SYNTH, clk_synth);
373                 if(ret < 0)
374                         return ret;
375         }
376
377         if (v_num) {
378                 ret = regmap_write(v_map, SDIF_SMPL_CTRL, 0x0);
379                 if(ret < 0)
380                         return ret;
381
382                 ret = regmap_write(v_map, SDIF_HALT, 0x0);
383                 if(ret < 0)
384                         return ret;
385
386                 ret = regmap_write(v_map, CLK_SYNTH, clk_synth);
387                 if(ret < 0)
388                         return ret;
389
390                 ret = regmap_write(v_map, SDIF_DISABLE, 0x0);
391                 if(ret < 0)
392                         return ret;
393
394                 ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
395                                                val, !(val & SDIF_BUSY),
396                                                PVT_POLL_DELAY_US,
397                                                PVT_POLL_TIMEOUT_US);
398                 if (ret)
399                         return ret;
400
401                 val = (BIT(pvt->c_num) - 1) | VM_CH_INIT |
402                       IP_POLL << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
403                 ret = regmap_write(v_map, SDIF_W, val);
404                 if (ret < 0)
405                         return ret;
406
407                 ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
408                                                val, !(val & SDIF_BUSY),
409                                                PVT_POLL_DELAY_US,
410                                                PVT_POLL_TIMEOUT_US);
411                 if (ret)
412                         return ret;
413
414                 val = CFG1_VOL_MEAS_MODE | CFG1_PARALLEL_OUT |
415                       CFG1_14_BIT | IP_CFG << SDIF_ADDR_SFT |
416                       SDIF_WRN_W | SDIF_PROG;
417                 ret = regmap_write(v_map, SDIF_W, val);
418                 if(ret < 0)
419                         return ret;
420
421                 ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
422                                                val, !(val & SDIF_BUSY),
423                                                PVT_POLL_DELAY_US,
424                                                PVT_POLL_TIMEOUT_US);
425                 if (ret)
426                         return ret;
427
428                 val = POWER_DELAY_CYCLE_64 | IP_TMR << SDIF_ADDR_SFT |
429                       SDIF_WRN_W | SDIF_PROG;
430                 ret = regmap_write(v_map, SDIF_W, val);
431                 if(ret < 0)
432                         return ret;
433
434                 ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
435                                                val, !(val & SDIF_BUSY),
436                                                PVT_POLL_DELAY_US,
437                                                PVT_POLL_TIMEOUT_US);
438                 if (ret)
439                         return ret;
440
441                 val = IP_RST_REL | IP_RUN_CONT | IP_AUTO | IP_VM_MODE |
442                       IP_CTRL << SDIF_ADDR_SFT |
443                       SDIF_WRN_W | SDIF_PROG;
444                 ret = regmap_write(v_map, SDIF_W, val);
445                 if(ret < 0)
446                         return ret;
447         }
448
449         return 0;
450 }
451
452 static struct regmap_config pvt_regmap_config = {
453         .reg_bits = 32,
454         .reg_stride = 4,
455         .val_bits = 32,
456 };
457
458 static int pvt_get_regmap(struct platform_device *pdev, char *reg_name,
459                           struct pvt_device *pvt)
460 {
461         struct device *dev = &pdev->dev;
462         struct regmap **reg_map;
463         void __iomem *io_base;
464
465         if (!strcmp(reg_name, "common"))
466                 reg_map = &pvt->c_map;
467         else if (!strcmp(reg_name, "ts"))
468                 reg_map = &pvt->t_map;
469         else if (!strcmp(reg_name, "pd"))
470                 reg_map = &pvt->p_map;
471         else if (!strcmp(reg_name, "vm"))
472                 reg_map = &pvt->v_map;
473         else
474                 return -EINVAL;
475
476         io_base = devm_platform_ioremap_resource_byname(pdev, reg_name);
477         if (IS_ERR(io_base))
478                 return PTR_ERR(io_base);
479
480         pvt_regmap_config.name = reg_name;
481         *reg_map = devm_regmap_init_mmio(dev, io_base, &pvt_regmap_config);
482         if (IS_ERR(*reg_map)) {
483                 dev_err(dev, "failed to init register map\n");
484                 return PTR_ERR(*reg_map);
485         }
486
487         return 0;
488 }
489
490 static void pvt_clk_disable(void *data)
491 {
492         struct pvt_device *pvt = data;
493
494         clk_disable_unprepare(pvt->clk);
495 }
496
497 static int pvt_clk_enable(struct device *dev, struct pvt_device *pvt)
498 {
499         int ret;
500
501         ret = clk_prepare_enable(pvt->clk);
502         if (ret)
503                 return ret;
504
505         return devm_add_action_or_reset(dev, pvt_clk_disable, pvt);
506 }
507
508 static void pvt_reset_control_assert(void *data)
509 {
510         struct pvt_device *pvt = data;
511
512         reset_control_assert(pvt->rst);
513 }
514
515 static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt)
516 {
517         int ret;
518
519         ret = reset_control_deassert(pvt->rst);
520         if (ret)
521                 return ret;
522
523         return devm_add_action_or_reset(dev, pvt_reset_control_assert, pvt);
524 }
525
526 static int mr75203_probe(struct platform_device *pdev)
527 {
528         u32 ts_num, vm_num, pd_num, ch_num, val, index, i;
529         const struct hwmon_channel_info **pvt_info;
530         struct device *dev = &pdev->dev;
531         u32 *temp_config, *in_config;
532         struct device *hwmon_dev;
533         struct pvt_device *pvt;
534         int ret;
535
536         pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL);
537         if (!pvt)
538                 return -ENOMEM;
539
540         ret = pvt_get_regmap(pdev, "common", pvt);
541         if (ret)
542                 return ret;
543
544         pvt->clk = devm_clk_get(dev, NULL);
545         if (IS_ERR(pvt->clk))
546                 return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n");
547
548         ret = pvt_clk_enable(dev, pvt);
549         if (ret) {
550                 dev_err(dev, "failed to enable clock\n");
551                 return ret;
552         }
553
554         pvt->rst = devm_reset_control_get_exclusive(dev, NULL);
555         if (IS_ERR(pvt->rst))
556                 return dev_err_probe(dev, PTR_ERR(pvt->rst),
557                                      "failed to get reset control\n");
558
559         ret = pvt_reset_control_deassert(dev, pvt);
560         if (ret)
561                 return dev_err_probe(dev, ret, "cannot deassert reset control\n");
562
563         ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val);
564         if(ret < 0)
565                 return ret;
566
567         ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT;
568         pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT;
569         vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT;
570         ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT;
571         pvt->t_num = ts_num;
572         pvt->p_num = pd_num;
573         pvt->v_num = vm_num;
574         pvt->c_num = ch_num;
575         val = 0;
576         if (ts_num)
577                 val++;
578         if (vm_num)
579                 val++;
580         if (!val)
581                 return -ENODEV;
582
583         pvt_info = devm_kcalloc(dev, val + 2, sizeof(*pvt_info), GFP_KERNEL);
584         if (!pvt_info)
585                 return -ENOMEM;
586         pvt_info[0] = &pvt_chip;
587         index = 1;
588
589         if (ts_num) {
590                 ret = pvt_get_regmap(pdev, "ts", pvt);
591                 if (ret)
592                         return ret;
593
594                 temp_config = devm_kcalloc(dev, ts_num + 1,
595                                            sizeof(*temp_config), GFP_KERNEL);
596                 if (!temp_config)
597                         return -ENOMEM;
598
599                 memset32(temp_config, HWMON_T_INPUT, ts_num);
600                 pvt_temp.config = temp_config;
601                 pvt_info[index++] = &pvt_temp;
602         }
603
604         if (pd_num) {
605                 ret = pvt_get_regmap(pdev, "pd", pvt);
606                 if (ret)
607                         return ret;
608         }
609
610         if (vm_num) {
611                 u32 total_ch;
612
613                 ret = pvt_get_regmap(pdev, "vm", pvt);
614                 if (ret)
615                         return ret;
616
617                 pvt->vm_idx = devm_kcalloc(dev, vm_num, sizeof(*pvt->vm_idx),
618                                            GFP_KERNEL);
619                 if (!pvt->vm_idx)
620                         return -ENOMEM;
621
622                 ret = device_property_read_u8_array(dev, "intel,vm-map",
623                                                     pvt->vm_idx, vm_num);
624                 if (ret) {
625                         /*
626                          * Incase intel,vm-map property is not defined, we
627                          * assume incremental channel numbers.
628                          */
629                         for (i = 0; i < vm_num; i++)
630                                 pvt->vm_idx[i] = i;
631                 } else {
632                         for (i = 0; i < vm_num; i++)
633                                 if (pvt->vm_idx[i] >= vm_num ||
634                                     pvt->vm_idx[i] == 0xff) {
635                                         pvt->v_num = i;
636                                         vm_num = i;
637                                         break;
638                                 }
639                 }
640
641                 total_ch = ch_num * vm_num;
642                 in_config = devm_kcalloc(dev, total_ch + 1,
643                                          sizeof(*in_config), GFP_KERNEL);
644                 if (!in_config)
645                         return -ENOMEM;
646
647                 memset32(in_config, HWMON_I_INPUT, total_ch);
648                 in_config[total_ch] = 0;
649                 pvt_in.config = in_config;
650
651                 pvt_info[index++] = &pvt_in;
652         }
653
654         ret = pvt_init(pvt);
655         if (ret) {
656                 dev_err(dev, "failed to init pvt: %d\n", ret);
657                 return ret;
658         }
659
660         pvt_chip_info.info = pvt_info;
661         hwmon_dev = devm_hwmon_device_register_with_info(dev, "pvt",
662                                                          pvt,
663                                                          &pvt_chip_info,
664                                                          NULL);
665
666         return PTR_ERR_OR_ZERO(hwmon_dev);
667 }
668
669 static const struct of_device_id moortec_pvt_of_match[] = {
670         { .compatible = "moortec,mr75203" },
671         { }
672 };
673 MODULE_DEVICE_TABLE(of, moortec_pvt_of_match);
674
675 static struct platform_driver moortec_pvt_driver = {
676         .driver = {
677                 .name = "moortec-pvt",
678                 .of_match_table = moortec_pvt_of_match,
679         },
680         .probe = mr75203_probe,
681 };
682 module_platform_driver(moortec_pvt_driver);
683
684 MODULE_LICENSE("GPL v2");