xref: /netbsd-src/sys/dev/usb/emdtv.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* $NetBSD: emdtv.c,v 1.12 2016/12/04 10:12:35 skrll 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.12 2016/12/04 10:12:35 skrll 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
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
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 }
152 
153 static int
154 emdtv_detach(device_t self, int flags)
155 {
156 	struct emdtv_softc *sc = device_private(self);
157 	usbd_status status;
158 
159 	sc->sc_dying = true;
160 
161 	emdtv_ir_detach(sc, flags);
162 	emdtv_dtv_detach(sc, flags);
163 
164 	if (sc->sc_iface != NULL) {
165 		status = usbd_set_interface(sc->sc_iface, 0);
166 		if (status != USBD_NORMAL_COMPLETION)
167 			aprint_error_dev(sc->sc_dev,
168 			    "couldn't stop stream: %s\n", usbd_errstr(status));
169 	}
170 
171 	emdtv_i2c_detach(sc, flags);
172 
173 	return 0;
174 }
175 
176 int
177 emdtv_activate(device_t self, enum devact act)
178 {
179 	struct emdtv_softc *sc = device_private(self);
180 
181 	switch (act) {
182 	case DVACT_DEACTIVATE:
183 		sc->sc_dying = true;
184 		break;
185 	}
186 
187 	return 0;
188 }
189 
190 static int
191 emdtv_rescan(device_t self, const char *ifattr, const int *locs)
192 {
193 	struct emdtv_softc *sc = device_private(self);
194 
195 	emdtv_dtv_rescan(sc, ifattr, locs);
196 
197 	return 0;
198 }
199 
200 static void
201 emdtv_childdet(device_t self, device_t child)
202 {
203 	struct emdtv_softc *sc = device_private(self);
204 
205 	if (child == sc->sc_cirdev)
206 		sc->sc_cirdev = NULL;
207 	if (child == sc->sc_dtvdev)
208 		sc->sc_dtvdev = NULL;
209 }
210 
211 static bool
212 emdtv_read_eeprom(struct emdtv_softc *sc)
213 {
214 	i2c_addr_t ee = EM28XX_I2C_ADDR_EEPROM;
215 	uint8_t buf, *p = sc->sc_eeprom;
216 	struct emdtv_eeprom *eeprom = (struct emdtv_eeprom *)sc->sc_eeprom;
217 	int block, size = sizeof(sc->sc_eeprom);
218 
219 	if (iic_exec(&sc->sc_i2c, I2C_OP_READ, ee, NULL, 0, NULL, 0, 0))
220 		return false;
221 	buf = 0;
222 	if (iic_exec(&sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, ee, &buf, 1,
223 	    NULL, 0, 0))
224 		return false;
225 	while (size > 0) {
226 		block = min(size, 16);
227 		if (iic_exec(&sc->sc_i2c, I2C_OP_READ, ee, NULL, 0,
228 		    p, block, 0))
229 			return false;
230 		size -= block;
231 		p += block;
232 	}
233 
234 	aprint_normal_dev(sc->sc_dev,
235 	    "id 0x%08x vendor 0x%04x product 0x%04x\n",
236 	    eeprom->id, eeprom->vendor, eeprom->product);
237 
238 	sc->sc_vendor = eeprom->vendor;
239 	sc->sc_product = eeprom->product;
240 
241 	return true;
242 }
243 
244 static void
245 emdtv_board_setup(struct emdtv_softc *sc)
246 {
247 	switch (sc->sc_vendor) {
248 	case USB_VENDOR_EMPIA:
249 		switch (sc->sc_product) {
250 		case USB_PRODUCT_EMPIA_EM2883:
251 			emdtv_write_1(sc, UR_GET_STATUS, EM28XX_XCLK_REG, 0x97);
252 			emdtv_write_1(sc, UR_GET_STATUS, EM28XX_I2C_CLK_REG,
253 			    0x40);
254 			delay(10000);
255 			emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0x2d);
256 			delay(10000);
257 			break;
258 		default:
259 			aprint_normal_dev(sc->sc_dev,
260 			    "unknown EMPIA board 0x%04x/0x%04x\n",
261 			    sc->sc_vendor, sc->sc_product);
262 			break;
263 		}
264 		break;
265 	case USB_VENDOR_AMD:
266 		switch (sc->sc_product) {
267 		case USB_PRODUCT_AMD_TV_WONDER_600_USB:
268 			emdtv_default_board_init(sc);
269 			break;
270 		default:
271 			aprint_normal_dev(sc->sc_dev,
272 			    "unknown AMD board 0x%04x/0x%04x\n",
273 			    sc->sc_vendor, sc->sc_product);
274 		}
275 		break;
276 	case USB_VENDOR_PINNACLE:
277 		switch (sc->sc_product) {
278 		case USB_PRODUCT_PINNACLE_PCTV800E:
279 			emdtv_default_board_init(sc);
280 			break;
281 		default:
282 			aprint_normal_dev(sc->sc_dev,
283 			    "unknown Pinnacle board 0x%04x/0x%04x\n",
284 			    sc->sc_vendor, sc->sc_product);
285 		}
286 		break;
287 	default:
288 		aprint_normal_dev(sc->sc_dev,
289 		    "unknown board 0x%04x:0x%04x\n",
290 		    sc->sc_vendor, sc->sc_product);
291 		break;
292 	}
293 }
294 
295 /*
296  * Register read/write
297  */
298 uint8_t
299 emdtv_read_1(struct emdtv_softc *sc, uint8_t req, uint16_t index)
300 {
301 	uint8_t val;
302 	emdtv_read_multi_1(sc, req, index, &val, 1);
303 	return val;
304 }
305 
306 void
307 emdtv_write_1(struct emdtv_softc *sc, uint8_t req, uint16_t index, uint8_t val)
308 {
309 	emdtv_write_multi_1(sc, req, index, &val, 1);
310 }
311 
312 void
313 emdtv_read_multi_1(struct emdtv_softc *sc, uint8_t req, uint16_t index,
314     uint8_t *datap, uint16_t count)
315 {
316 	usb_device_request_t request;
317 	usbd_status status;
318 
319 	request.bmRequestType = UT_READ_VENDOR_DEVICE;
320 	request.bRequest = req;
321 	USETW(request.wValue, 0x0000);
322 	USETW(request.wIndex, index);
323 	USETW(request.wLength, count);
324 
325 	KERNEL_LOCK(1, curlwp);
326 	status = usbd_do_request(sc->sc_udev, &request, datap);
327 	KERNEL_UNLOCK_ONE(curlwp);
328 
329 	if (status != USBD_NORMAL_COMPLETION)
330 		aprint_error_dev(sc->sc_dev, "couldn't read %x/%x: %s\n",
331 		    req, index, usbd_errstr(status));
332 
333 	if (emdtv_debug_regs) {
334 		int i;
335 		printf("%s [%s] c0 %02x 00 00 %02x 00 01 00 <<<",
336 		    __func__, status == 0 ? " OK" : "NOK", req, index);
337 		for (i = 0; status == 0 && i < count; i++)
338 			printf(" %02x", datap[i]);
339 		printf("\n");
340 	}
341 }
342 
343 void
344 emdtv_write_multi_1(struct emdtv_softc *sc, uint8_t req, uint16_t index,
345     const uint8_t *datap, uint16_t count)
346 {
347 	usb_device_request_t request;
348 	usbd_status status;
349 
350 	request.bmRequestType = UT_WRITE_VENDOR_DEVICE;
351 	request.bRequest = req;
352 	USETW(request.wValue, 0x0000);
353 	USETW(request.wIndex, index);
354 	USETW(request.wLength, count);
355 
356 	KERNEL_LOCK(1, curlwp);
357 	status = usbd_do_request(sc->sc_udev, &request, __UNCONST(datap));
358 	KERNEL_UNLOCK_ONE(curlwp);
359 
360 	if (status != USBD_NORMAL_COMPLETION)
361 		aprint_error_dev(sc->sc_dev, "couldn't read %x/%x: %s\n",
362 		    req, index, usbd_errstr(status));
363 
364 	if (emdtv_debug_regs) {
365 		int i;
366 		printf("%s [%s] 40 %02x 00 00 %02x 00 %02x 00 >>>",
367 		    __func__, status == 0 ? " OK" : "NOK",
368 		    req, index, count);
369 		for (i = 0; i < count; ++i)
370 			printf(" %02x", datap[i]);
371 		printf("\n");
372 	}
373 }
374 
375 bool
376 emdtv_gpio_ctl(struct emdtv_softc *sc, emdtv_gpio_reg_t gpioreg, bool onoff)
377 {
378 	const struct emdtv_board *eb = sc->sc_board;
379 	uint16_t gpio_value, reg;
380 	uint8_t gpio;
381 	uint8_t eeprom_offset = 0x3c;
382 	uint8_t val;
383 
384 	if (sc->sc_board->eb_manual_gpio == false) {
385 		val = eeprom_offset + gpioreg;
386 		emdtv_write_1(sc, 0x03, 0xa0, val);
387 		gpio_value = emdtv_read_1(sc, 0x02, 0xa0);
388 	} else {
389 		const struct emdtv_gpio_regs *r = &eb->eb_gpio_regs;
390 		switch (gpioreg) {
391 		case EMDTV_GPIO_TS1_ON:
392 			gpio_value = r->ts1_on;
393 			break;
394 		case EMDTV_GPIO_ANALOG_ON:
395 			gpio_value = r->a_on;
396 			break;
397 		case EMDTV_GPIO_TUNER1_ON:
398 			gpio_value = r->t1_on;
399 			break;
400 		case EMDTV_GPIO_TUNER1_RESET:
401 			gpio_value = r->t1_reset;
402 				break;
403 		case EMDTV_GPIO_DEMOD1_RESET:
404 			gpio_value = r->d1_reset;
405 			break;
406 		default:
407 			aprint_error_dev(sc->sc_dev,
408 			    "unknown gpio reg %d\n", gpioreg);
409 			return false;
410 		}
411 	}
412 
413 	if ((gpio_value & 0x80) == 0) {
414 		aprint_error_dev(sc->sc_dev,
415 		    "gpio reg %d not enabled\n", gpioreg);
416 		return false;
417 	}
418 
419 	reg = gpio_value & 0x10 ? 0x04 : 0x08;
420 	gpio = emdtv_read_1(sc, UR_GET_STATUS, reg);
421 	if ((gpio_value & 0x40) == 0) {
422 		gpio &= ~((uint8_t)(1 << (gpio_value & 7)));
423 
424 		if (onoff)
425 			gpio |= ((gpio_value >> 5) & 1) << (gpio_value & 7);
426 		else
427 			gpio |= (((gpio_value >> 5) & 1) ^ 1) <<
428 			    (gpio_value & 7);
429 		emdtv_write_1(sc, UR_GET_STATUS, reg, gpio);
430 	} else {
431 		gpio &= ~((uint8_t)(1 << (gpio_value & 0xf)));
432 
433 		gpio |= ((gpio_value >> 5) & 1) << (gpio_value & 7);
434 		emdtv_write_1(sc, UR_GET_STATUS, reg, gpio);
435 		usbd_delay_ms(sc->sc_udev, 100);
436 
437 		gpio &= ~((uint8_t)(1 << (gpio_value & 0xf)));
438 		gpio |= (((gpio_value >> 5) & 1) ^ 1) << (gpio_value & 7);
439 		emdtv_write_1(sc, UR_GET_STATUS, reg, gpio);
440 		usbd_delay_ms(sc->sc_udev, 100);
441 	}
442 
443 	return true;
444 }
445 
446 static void
447 emdtv_default_board_init(struct emdtv_softc *sc)
448 {
449 	emdtv_write_1(sc, UR_GET_STATUS, EM28XX_XCLK_REG, 0x27);
450 	emdtv_write_1(sc, UR_GET_STATUS, EM28XX_I2C_CLK_REG, 0x40);
451 	emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0xff);
452 	emdtv_write_1(sc, UR_GET_STATUS, 0x04, 0x00);
453 	usbd_delay_ms(sc->sc_udev, 100);
454 	emdtv_write_1(sc, UR_GET_STATUS, 0x04, 0x08);
455 	usbd_delay_ms(sc->sc_udev, 100);
456 	emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0xff);
457 	usbd_delay_ms(sc->sc_udev, 50);
458 	emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0x2d);
459 	usbd_delay_ms(sc->sc_udev, 50);
460 	emdtv_write_1(sc, UR_GET_STATUS, 0x08, 0x3d);
461 	//emdtv_write_1(sc, UR_GET_STATUS, 0x0f, 0xa7);
462 	usbd_delay_ms(sc->sc_udev, 10);
463 }
464 
465 MODULE(MODULE_CLASS_DRIVER, emdtv, "cir,lg3303,xc3028");
466 
467 #ifdef _MODULE
468 #include "ioconf.c"
469 #endif
470 
471 static int
472 emdtv_modcmd(modcmd_t cmd, void *opaque)
473 {
474 	switch (cmd) {
475 	case MODULE_CMD_INIT:
476 #ifdef _MODULE
477 		return config_init_component(cfdriver_ioconf_emdtv,
478 		    cfattach_ioconf_emdtv, cfdata_ioconf_emdtv);
479 #else
480 		return 0;
481 #endif
482 	case MODULE_CMD_FINI:
483 #ifdef _MODULE
484 		return config_fini_component(cfdriver_ioconf_emdtv,
485 		    cfattach_ioconf_emdtv, cfdata_ioconf_emdtv);
486 #else
487 		return 0;
488 #endif
489 	default:
490 		return ENOTTY;
491 	}
492 }
493