Path: blob/master/drivers/media/dvb/dvb-usb/a800.c
15111 views
/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T1* USB2.0 (A800) DVB-T receiver.2*3* Copyright (C) 2005 Patrick Boettcher ([email protected])4*5* Thanks to6* - AVerMedia who kindly provided information and7* - Glen Harris who suffered from my mistakes during development.8*9* This program is free software; you can redistribute it and/or modify it10* under the terms of the GNU General Public License as published by the Free11* Software Foundation, version 2.12*13* see Documentation/dvb/README.dvb-usb for more information14*/15#include "dibusb.h"1617static int debug;18module_param(debug, int, 0644);19MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);2021DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);2223#define deb_rc(args...) dprintk(debug,0x01,args)2425static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)26{27/* do nothing for the AVerMedia */28return 0;29}3031/* assure to put cold to 0 for iManufacturer == 1 */32static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,33struct dvb_usb_device_description **desc, int *cold)34{35*cold = udev->descriptor.iManufacturer != 1;36return 0;37}3839static struct rc_map_table rc_map_a800_table[] = {40{ 0x0201, KEY_MODE }, /* SOURCE */41{ 0x0200, KEY_POWER2 }, /* POWER */42{ 0x0205, KEY_1 }, /* 1 */43{ 0x0206, KEY_2 }, /* 2 */44{ 0x0207, KEY_3 }, /* 3 */45{ 0x0209, KEY_4 }, /* 4 */46{ 0x020a, KEY_5 }, /* 5 */47{ 0x020b, KEY_6 }, /* 6 */48{ 0x020d, KEY_7 }, /* 7 */49{ 0x020e, KEY_8 }, /* 8 */50{ 0x020f, KEY_9 }, /* 9 */51{ 0x0212, KEY_LEFT }, /* L / DISPLAY */52{ 0x0211, KEY_0 }, /* 0 */53{ 0x0213, KEY_RIGHT }, /* R / CH RTN */54{ 0x0217, KEY_CAMERA }, /* SNAP SHOT */55{ 0x0210, KEY_LAST }, /* 16-CH PREV */56{ 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */57{ 0x020c, KEY_ZOOM }, /* FULL SCREEN */58{ 0x021f, KEY_VOLUMEUP }, /* VOL UP */59{ 0x0214, KEY_MUTE }, /* MUTE */60{ 0x0208, KEY_AUDIO }, /* AUDIO */61{ 0x0219, KEY_RECORD }, /* RECORD */62{ 0x0218, KEY_PLAY }, /* PLAY */63{ 0x021b, KEY_STOP }, /* STOP */64{ 0x021a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */65{ 0x021d, KEY_BACK }, /* << / RED */66{ 0x021c, KEY_FORWARD }, /* >> / YELLOW */67{ 0x0203, KEY_TEXT }, /* TELETEXT */68{ 0x0204, KEY_EPG }, /* EPG */69{ 0x0215, KEY_MENU }, /* MENU */7071{ 0x0303, KEY_CHANNELUP }, /* CH UP */72{ 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */73{ 0x0301, KEY_FIRST }, /* |<< / GREEN */74{ 0x0300, KEY_LAST }, /* >>| / BLUE */7576};7778static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)79{80int ret;81u8 *key = kmalloc(5, GFP_KERNEL);82if (!key)83return -ENOMEM;8485if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),860x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,872000) != 5) {88ret = -ENODEV;89goto out;90}9192/* call the universal NEC remote processor, to find out the key's state and event */93dvb_usb_nec_rc_key_to_event(d,key,event,state);94if (key[0] != 0)95deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);96ret = 0;97out:98kfree(key);99return ret;100}101102/* USB Driver stuff */103static struct dvb_usb_device_properties a800_properties;104105static int a800_probe(struct usb_interface *intf,106const struct usb_device_id *id)107{108return dvb_usb_device_init(intf, &a800_properties,109THIS_MODULE, NULL, adapter_nr);110}111112/* do not change the order of the ID table */113static struct usb_device_id a800_table [] = {114/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) },115/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) },116{ } /* Terminating entry */117};118MODULE_DEVICE_TABLE (usb, a800_table);119120static struct dvb_usb_device_properties a800_properties = {121.caps = DVB_USB_IS_AN_I2C_ADAPTER,122123.usb_ctrl = CYPRESS_FX2,124.firmware = "dvb-usb-avertv-a800-02.fw",125126.num_adapters = 1,127.adapter = {128{129.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,130.pid_filter_count = 32,131.streaming_ctrl = dibusb2_0_streaming_ctrl,132.pid_filter = dibusb_pid_filter,133.pid_filter_ctrl = dibusb_pid_filter_ctrl,134135.frontend_attach = dibusb_dib3000mc_frontend_attach,136.tuner_attach = dibusb_dib3000mc_tuner_attach,137138/* parameter for the MPEG2-data transfer */139.stream = {140.type = USB_BULK,141.count = 7,142.endpoint = 0x06,143.u = {144.bulk = {145.buffersize = 4096,146}147}148},149150.size_of_priv = sizeof(struct dibusb_state),151},152},153154.power_ctrl = a800_power_ctrl,155.identify_state = a800_identify_state,156157.rc.legacy = {158.rc_interval = DEFAULT_RC_INTERVAL,159.rc_map_table = rc_map_a800_table,160.rc_map_size = ARRAY_SIZE(rc_map_a800_table),161.rc_query = a800_rc_query,162},163164.i2c_algo = &dibusb_i2c_algo,165166.generic_bulk_ctrl_endpoint = 0x01,167.num_device_descs = 1,168.devices = {169{ "AVerMedia AverTV DVB-T USB 2.0 (A800)",170{ &a800_table[0], NULL },171{ &a800_table[1], NULL },172},173}174};175176static struct usb_driver a800_driver = {177.name = "dvb_usb_a800",178.probe = a800_probe,179.disconnect = dvb_usb_device_exit,180.id_table = a800_table,181};182183/* module stuff */184static int __init a800_module_init(void)185{186int result;187if ((result = usb_register(&a800_driver))) {188err("usb_register failed. Error number %d",result);189return result;190}191192return 0;193}194195static void __exit a800_module_exit(void)196{197/* deregister this driver from the USB subsystem */198usb_deregister(&a800_driver);199}200201module_init (a800_module_init);202module_exit (a800_module_exit);203204MODULE_AUTHOR("Patrick Boettcher <[email protected]>");205MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");206MODULE_VERSION("1.0");207MODULE_LICENSE("GPL");208209210