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