1 /* $NetBSD: emdtv.c,v 1.18 2022/06/26 22:49:09 riastradh Exp $ */
2 
3 /*-
4  * Copyright (c) 2008, 2011 Jared D. McNeill <jmcneill@invisible.ca>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: emdtv.c,v 1.18 2022/06/26 22:49:09 riastradh Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/device.h>
35 #include <sys/lwp.h>
36 #include <sys/module.h>
37 #include <sys/conf.h>
38 
39 #include <dev/usb/usb.h>
40 #include <dev/usb/usbdi.h>
41 #include <dev/usb/usbdi_util.h>
42 #include <dev/usb/usbdivar.h>
43 #include <dev/usb/usbdevs.h>
44 
45 #include <dev/usb/emdtvvar.h>
46 #include <dev/usb/emdtvreg.h>
47 
48 static int          emdtv_match(device_t, cfdata_t, void *);
49 static void         emdtv_attach(device_t, device_t, void *);
50 static int          emdtv_detach(device_t, int);
51 static int          emdtv_rescan(device_t, const char *, const int *);
52 static void         emdtv_childdet(device_t, device_t);
53 static int          emdtv_activate(device_t, enum devact);
54 
55 static bool         emdtv_read_eeprom(struct emdtv_softc *);
56 static void         emdtv_board_setup(struct emdtv_softc *);
57 
58 static void         emdtv_default_board_init(struct emdtv_softc *);
59 
60 CFATTACH_DECL2_NEW(emdtv, sizeof(struct emdtv_softc),
61     emdtv_match, emdtv_attach, emdtv_detach, emdtv_activate,
62     emdtv_rescan, emdtv_childdet);
63 
64 static const struct usb_devno emdtv_devices[] = {
65           { USB_VENDOR_AMD,   USB_PRODUCT_AMD_TV_WONDER_600_USB },
66           { USB_VENDOR_PINNACLE,        USB_PRODUCT_PINNACLE_PCTV800E },
67 };
68 
69 int emdtv_debug_regs = 0;
70 
71 static int
emdtv_match(device_t parent,cfdata_t match,void * opaque)72 emdtv_match(device_t parent, cfdata_t match, void *opaque)
73 {
74           struct usb_attach_arg *uaa = opaque;
75 
76           return usb_lookup(emdtv_devices, uaa->uaa_vendor, uaa->uaa_product) != NULL ?
77               UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
78 }
79 
80 static void
emdtv_attach(device_t parent,device_t self,void * opaque)81 emdtv_attach(device_t parent, device_t self, void *opaque)
82 {
83           struct emdtv_softc *sc = device_private(self);
84           struct usb_attach_arg *uaa = opaque;
85           struct usbd_device *dev = uaa->uaa_device;
86           usbd_status status;
87           char *devinfo;
88 
89           devinfo = usbd_devinfo_alloc(dev, 0);
90           aprint_naive("\n");
91           aprint_normal(": %s\n", devinfo);
92           usbd_devinfo_free(devinfo);
93 
94           sc->sc_dev = self;
95           sc->sc_udev = dev;
96 
97           sc->sc_vendor = uaa->uaa_vendor;
98           sc->sc_product = uaa->uaa_product;
99 
100           emdtv_i2c_attach(sc);
101 
102           emdtv_read_eeprom(sc);
103 
104           sc->sc_board = emdtv_board_lookup(sc->sc_vendor, sc->sc_product);
105           if (sc->sc_board == NULL) {
106                     aprint_error_dev(sc->sc_dev,
107                         "unsupported board 0x%04x:0x%04x\n",
108                         sc->sc_vendor, sc->sc_product);
109                     sc->sc_dying = true;
110                     return;
111           }
112 
113           emdtv_write_1(sc, 0x02, 0xa0, 0x23);
114           if (emdtv_read_1(sc, UR_GET_STATUS, 0x05) != 0) {
115                     (void)emdtv_read_1(sc, 0x02, 0xa0);
116                     if (emdtv_read_1(sc, 0x02, 0xa0) & 0x08)
117                               aprint_debug_dev(sc->sc_dev,
118                                   "board requires manual gpio configuration\n");
119           }
120 
121           emdtv_board_setup(sc);
122 
123           emdtv_gpio_ctl(sc, EMDTV_GPIO_ANALOG_ON, false);
124           emdtv_gpio_ctl(sc, EMDTV_GPIO_TS1_ON, false);
125           usbd_delay_ms(sc->sc_udev, 100);
126           emdtv_gpio_ctl(sc, EMDTV_GPIO_ANALOG_ON, true);
127           emdtv_gpio_ctl(sc, EMDTV_GPIO_TUNER1_ON, true);
128           usbd_delay_ms(sc->sc_udev, 100);
129 
130           status = usbd_set_config_no(sc->sc_udev, 1, 1);
131         if (status != USBD_NORMAL_COMPLETION) {
132                     aprint_error_dev(sc->sc_dev, "failed to set configuration"
133                         ", err=%s\n", usbd_errstr(status));
134                     return;
135           }
136 
137           status = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
138           if (status != USBD_NORMAL_COMPLETION) {
139                     aprint_error_dev(sc->sc_dev, "couldn't find iface handle\n");
140                     return;
141           }
142 
143           status = usbd_set_interface(sc->sc_iface, 1);
144           if (status != USBD_NORMAL_COMPLETION) {
145                     aprint_error_dev(sc->sc_dev, "couldn't set interface\n");
146                     return;
147           }
148 
149           emdtv_dtv_attach(sc);
150           emdtv_ir_attach(sc);
151           sc->sc_subdevs_attached = true;
152 }
153 
154 static int
emdtv_detach(device_t self,int flags)155 emdtv_detach(device_t self, int flags)
156 {
157           struct emdtv_softc *sc = device_private(self);
158           usbd_status status;
159           int error;
160 
161           sc->sc_dying = true;
162 
163           error = config_detach_children(self, flags);
164           if (error)
165                     return error;
166 
167           if (sc->sc_subdevs_attached) {
168                     emdtv_ir_detach(sc, flags);
169                     emdtv_dtv_detach(sc, flags);
170           }
171 
172           if (sc->sc_iface != NULL) {
173                     status = usbd_set_interface(sc->sc_iface, 0);
174                     if (status != USBD_NORMAL_COMPLETION)
175                               aprint_error_dev(sc->sc_dev,
176                                   "couldn't stop stream: %s\n", usbd_errstr(status));
177           }
178 
179           emdtv_i2c_detach(sc, flags);
180 
181           return 0;
182 }
183 
184 int
emdtv_activate(device_t self,enum devact act)185 emdtv_activate(device_t self, enum devact act)
186 {
187           struct emdtv_softc *sc = device_private(self);
188 
189           switch (act) {
190           case DVACT_DEACTIVATE:
191                     sc->sc_dying = true;
192                     break;
193           }
194 
195           return 0;
196 }
197 
198 static int
emdtv_rescan(device_t self,const char * ifattr,const int * locs)199 emdtv_rescan(device_t self, const char *ifattr, const int *locs)
200 {
201           struct emdtv_softc *sc = device_private(self);
202 
203           emdtv_dtv_rescan(sc, ifattr, locs);
204 
205           return 0;
206 }
207 
208 static void
emdtv_childdet(device_t self,device_t child)209 emdtv_childdet(device_t self, device_t child)
210 {
211           struct emdtv_softc *sc = device_private(self);
212 
213           if (child == sc->sc_cirdev)
214                     sc->sc_cirdev = NULL;
215           if (child == sc->sc_dtvdev)
216                     sc->sc_dtvdev = NULL;
217 }
218 
219 static bool
emdtv_read_eeprom(struct emdtv_softc * sc)220 emdtv_read_eeprom(struct emdtv_softc *sc)
221 {
222           i2c_addr_t ee = EM28XX_I2C_ADDR_EEPROM;
223           uint8_t buf, *p = sc->sc_eeprom;
224           struct emdtv_eeprom *eeprom = (struct emdtv_eeprom *)sc->sc_eeprom;
225           int block, size = sizeof(sc->sc_eeprom);
226 
227           if (iic_exec(&sc->sc_i2c, I2C_OP_READ, ee, NULL, 0, NULL, 0, 0))
228                     return false;
229           buf = 0;
230           if (iic_exec(&sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, ee, &buf, 1,
231               NULL, 0, 0))
232                     return false;
233           while (size > 0) {
234                     block = uimin(size, 16);
235                     if (iic_exec(&sc->sc_i2c, I2C_OP_READ, ee, NULL, 0,
236                         p, block, 0))
237                               return false;
238                     size -= block;
239                     p += block;
240           }
241 
242           aprint_normal_dev(sc->sc_dev,
243               "id 0x%08x vendor 0x%04x product 0x%04x\n",
244               eeprom->id, eeprom->vendor, eeprom->product);
245 
246           sc->sc_vendor = eeprom->vendor;
247           sc->sc_product = eeprom->product;
248 
249           return true;
250 }
251 
252 static void
emdtv_board_setup(struct emdtv_softc * sc)253 emdtv_board_setup(struct emdtv_softc *sc)
254 {
255           switch (sc->sc_vendor) {
256           case USB_VENDOR_EMPIA:
257                     switch (sc->sc_product) {
258                     case USB_PRODUCT_EMPIA_EM2883:
259                               emdtv_write_1(sc, UR_GET_STATUS, EM28XX_XCLK_REG, 0x97);
260                               emdtv_write_1(sc, UR_GET_STATUS, EM28XX_I2C_CLK_REG,
261                                   0x40);
262                               delay(10000);
263                               emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0x2d);
264                               delay(10000);
265                               break;
266                     default:
267                               aprint_normal_dev(sc->sc_dev,
268                                   "unknown EMPIA board 0x%04x/0x%04x\n",
269                                   sc->sc_vendor, sc->sc_product);
270                               break;
271                     }
272                     break;
273           case USB_VENDOR_AMD:
274                     switch (sc->sc_product) {
275                     case USB_PRODUCT_AMD_TV_WONDER_600_USB:
276                               emdtv_default_board_init(sc);
277                               break;
278                     default:
279                               aprint_normal_dev(sc->sc_dev,
280                                   "unknown AMD board 0x%04x/0x%04x\n",
281                                   sc->sc_vendor, sc->sc_product);
282                     }
283                     break;
284           case USB_VENDOR_PINNACLE:
285                     switch (sc->sc_product) {
286                     case USB_PRODUCT_PINNACLE_PCTV800E:
287                               emdtv_default_board_init(sc);
288                               break;
289                     default:
290                               aprint_normal_dev(sc->sc_dev,
291                                   "unknown Pinnacle board 0x%04x/0x%04x\n",
292                                   sc->sc_vendor, sc->sc_product);
293                     }
294                     break;
295           default:
296                     aprint_normal_dev(sc->sc_dev,
297                         "unknown board 0x%04x:0x%04x\n",
298                         sc->sc_vendor, sc->sc_product);
299                     break;
300           }
301 }
302 
303 /*
304  * Register read/write
305  */
306 uint8_t
emdtv_read_1(struct emdtv_softc * sc,uint8_t req,uint16_t index)307 emdtv_read_1(struct emdtv_softc *sc, uint8_t req, uint16_t index)
308 {
309           uint8_t val;
310           emdtv_read_multi_1(sc, req, index, &val, 1);
311           return val;
312 }
313 
314 void
emdtv_write_1(struct emdtv_softc * sc,uint8_t req,uint16_t index,uint8_t val)315 emdtv_write_1(struct emdtv_softc *sc, uint8_t req, uint16_t index, uint8_t val)
316 {
317           emdtv_write_multi_1(sc, req, index, &val, 1);
318 }
319 
320 void
emdtv_read_multi_1(struct emdtv_softc * sc,uint8_t req,uint16_t index,uint8_t * datap,uint16_t count)321 emdtv_read_multi_1(struct emdtv_softc *sc, uint8_t req, uint16_t index,
322     uint8_t *datap, uint16_t count)
323 {
324           usb_device_request_t request;
325           usbd_status status;
326 
327           request.bmRequestType = UT_READ_VENDOR_DEVICE;
328           request.bRequest = req;
329           USETW(request.wValue, 0x0000);
330           USETW(request.wIndex, index);
331           USETW(request.wLength, count);
332 
333           KERNEL_LOCK(1, curlwp);
334           status = usbd_do_request(sc->sc_udev, &request, datap);
335           KERNEL_UNLOCK_ONE(curlwp);
336 
337           if (status != USBD_NORMAL_COMPLETION) {
338                     aprint_error_dev(sc->sc_dev, "couldn't read %x/%x: %s\n",
339                         req, index, usbd_errstr(status));
340                     memset(datap, 0, count);
341           }
342 
343           if (emdtv_debug_regs) {
344                     int i;
345                     printf("%s [%s] c0 %02x 00 00 %02x 00 01 00 <<<",
346                         __func__, status == 0 ? " OK" : "NOK", req, index);
347                     for (i = 0; status == 0 && i < count; i++)
348                               printf(" %02x", datap[i]);
349                     printf("\n");
350           }
351 }
352 
353 void
emdtv_write_multi_1(struct emdtv_softc * sc,uint8_t req,uint16_t index,const uint8_t * datap,uint16_t count)354 emdtv_write_multi_1(struct emdtv_softc *sc, uint8_t req, uint16_t index,
355     const uint8_t *datap, uint16_t count)
356 {
357           usb_device_request_t request;
358           usbd_status status;
359 
360           request.bmRequestType = UT_WRITE_VENDOR_DEVICE;
361           request.bRequest = req;
362           USETW(request.wValue, 0x0000);
363           USETW(request.wIndex, index);
364           USETW(request.wLength, count);
365 
366           KERNEL_LOCK(1, curlwp);
367           status = usbd_do_request(sc->sc_udev, &request, __UNCONST(datap));
368           KERNEL_UNLOCK_ONE(curlwp);
369 
370           if (status != USBD_NORMAL_COMPLETION)
371                     aprint_error_dev(sc->sc_dev, "couldn't read %x/%x: %s\n",
372                         req, index, usbd_errstr(status));
373 
374           if (emdtv_debug_regs) {
375                     int i;
376                     printf("%s [%s] 40 %02x 00 00 %02x 00 %02x 00 >>>",
377                         __func__, status == 0 ? " OK" : "NOK",
378                         req, index, count);
379                     for (i = 0; i < count; ++i)
380                               printf(" %02x", datap[i]);
381                     printf("\n");
382           }
383 }
384 
385 bool
emdtv_gpio_ctl(struct emdtv_softc * sc,emdtv_gpio_reg_t gpioreg,bool onoff)386 emdtv_gpio_ctl(struct emdtv_softc *sc, emdtv_gpio_reg_t gpioreg, bool onoff)
387 {
388           const struct emdtv_board *eb = sc->sc_board;
389           uint16_t gpio_value, reg;
390           uint8_t gpio;
391           uint8_t eeprom_offset = 0x3c;
392           uint8_t val;
393 
394           if (sc->sc_board->eb_manual_gpio == false) {
395                     val = eeprom_offset + gpioreg;
396                     emdtv_write_1(sc, 0x03, 0xa0, val);
397                     gpio_value = emdtv_read_1(sc, 0x02, 0xa0);
398           } else {
399                     const struct emdtv_gpio_regs *r = &eb->eb_gpio_regs;
400                     switch (gpioreg) {
401                     case EMDTV_GPIO_TS1_ON:
402                               gpio_value = r->ts1_on;
403                               break;
404                     case EMDTV_GPIO_ANALOG_ON:
405                               gpio_value = r->a_on;
406                               break;
407                     case EMDTV_GPIO_TUNER1_ON:
408                               gpio_value = r->t1_on;
409                               break;
410                     case EMDTV_GPIO_TUNER1_RESET:
411                               gpio_value = r->t1_reset;
412                                         break;
413                     case EMDTV_GPIO_DEMOD1_RESET:
414                               gpio_value = r->d1_reset;
415                               break;
416                     default:
417                               aprint_error_dev(sc->sc_dev,
418                                   "unknown gpio reg %d\n", gpioreg);
419                               return false;
420                     }
421           }
422 
423           if ((gpio_value & 0x80) == 0) {
424                     aprint_error_dev(sc->sc_dev,
425                         "gpio reg %d not enabled\n", gpioreg);
426                     return false;
427           }
428 
429           reg = gpio_value & 0x10 ? 0x04 : 0x08;
430           gpio = emdtv_read_1(sc, UR_GET_STATUS, reg);
431           if ((gpio_value & 0x40) == 0) {
432                     gpio &= ~((uint8_t)(1 << (gpio_value & 7)));
433 
434                     if (onoff)
435                               gpio |= ((gpio_value >> 5) & 1) << (gpio_value & 7);
436                     else
437                               gpio |= (((gpio_value >> 5) & 1) ^ 1) <<
438                                   (gpio_value & 7);
439                     emdtv_write_1(sc, UR_GET_STATUS, reg, gpio);
440           } else {
441                     gpio &= ~((uint8_t)(1 << (gpio_value & 0xf)));
442 
443                     gpio |= ((gpio_value >> 5) & 1) << (gpio_value & 7);
444                     emdtv_write_1(sc, UR_GET_STATUS, reg, gpio);
445                     usbd_delay_ms(sc->sc_udev, 100);
446 
447                     gpio &= ~((uint8_t)(1 << (gpio_value & 0xf)));
448                     gpio |= (((gpio_value >> 5) & 1) ^ 1) << (gpio_value & 7);
449                     emdtv_write_1(sc, UR_GET_STATUS, reg, gpio);
450                     usbd_delay_ms(sc->sc_udev, 100);
451           }
452 
453           return true;
454 }
455 
456 static void
emdtv_default_board_init(struct emdtv_softc * sc)457 emdtv_default_board_init(struct emdtv_softc *sc)
458 {
459           emdtv_write_1(sc, UR_GET_STATUS, EM28XX_XCLK_REG, 0x27);
460           emdtv_write_1(sc, UR_GET_STATUS, EM28XX_I2C_CLK_REG, 0x40);
461           emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0xff);
462           emdtv_write_1(sc, UR_GET_STATUS, 0x04, 0x00);
463           usbd_delay_ms(sc->sc_udev, 100);
464           emdtv_write_1(sc, UR_GET_STATUS, 0x04, 0x08);
465           usbd_delay_ms(sc->sc_udev, 100);
466           emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0xff);
467           usbd_delay_ms(sc->sc_udev, 50);
468           emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0x2d);
469           usbd_delay_ms(sc->sc_udev, 50);
470           emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0x3d);
471           //emdtv_write_1(sc, UR_GET_STATUS, 0x0f, 0xa7);
472           usbd_delay_ms(sc->sc_udev, 10);
473 }
474 
475 MODULE(MODULE_CLASS_DRIVER, emdtv, "cir,lg3303,xc3028");
476 
477 #ifdef _MODULE
478 #include "ioconf.c"
479 #endif
480 
481 static int
emdtv_modcmd(modcmd_t cmd,void * opaque)482 emdtv_modcmd(modcmd_t cmd, void *opaque)
483 {
484           switch (cmd) {
485           case MODULE_CMD_INIT:
486 #ifdef _MODULE
487                     return config_init_component(cfdriver_ioconf_emdtv,
488                         cfattach_ioconf_emdtv, cfdata_ioconf_emdtv);
489 #else
490                     return 0;
491 #endif
492           case MODULE_CMD_FINI:
493 #ifdef _MODULE
494                     return config_fini_component(cfdriver_ioconf_emdtv,
495                         cfattach_ioconf_emdtv, cfdata_ioconf_emdtv);
496 #else
497                     return 0;
498 #endif
499           default:
500                     return ENOTTY;
501           }
502 }
503