162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* Common methods for dibusb-based-receivers. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de) 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "dibusb.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* Max transfer size done by I2C transfer functions */ 1262306a36Sopenharmony_ci#define MAX_XFER_SIZE 64 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistatic int debug; 1562306a36Sopenharmony_cimodule_param(debug, int, 0644); 1662306a36Sopenharmony_ciMODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS); 1762306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define deb_info(args...) dprintk(debug,0x01,args) 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* common stuff used by the different dibusb modules */ 2262306a36Sopenharmony_ciint dibusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci if (adap->priv != NULL) { 2562306a36Sopenharmony_ci struct dibusb_state *st = adap->priv; 2662306a36Sopenharmony_ci if (st->ops.fifo_ctrl != NULL) 2762306a36Sopenharmony_ci if (st->ops.fifo_ctrl(adap->fe_adap[0].fe, onoff)) { 2862306a36Sopenharmony_ci err("error while controlling the fifo of the demod."); 2962306a36Sopenharmony_ci return -ENODEV; 3062306a36Sopenharmony_ci } 3162306a36Sopenharmony_ci } 3262306a36Sopenharmony_ci return 0; 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ciEXPORT_SYMBOL(dibusb_streaming_ctrl); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ciint dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci if (adap->priv != NULL) { 3962306a36Sopenharmony_ci struct dibusb_state *st = adap->priv; 4062306a36Sopenharmony_ci if (st->ops.pid_ctrl != NULL) 4162306a36Sopenharmony_ci st->ops.pid_ctrl(adap->fe_adap[0].fe, 4262306a36Sopenharmony_ci index, pid, onoff); 4362306a36Sopenharmony_ci } 4462306a36Sopenharmony_ci return 0; 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ciEXPORT_SYMBOL(dibusb_pid_filter); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ciint dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci if (adap->priv != NULL) { 5162306a36Sopenharmony_ci struct dibusb_state *st = adap->priv; 5262306a36Sopenharmony_ci if (st->ops.pid_parse != NULL) 5362306a36Sopenharmony_ci if (st->ops.pid_parse(adap->fe_adap[0].fe, onoff) < 0) 5462306a36Sopenharmony_ci err("could not handle pid_parser"); 5562306a36Sopenharmony_ci } 5662306a36Sopenharmony_ci return 0; 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ciEXPORT_SYMBOL(dibusb_pid_filter_ctrl); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ciint dibusb_power_ctrl(struct dvb_usb_device *d, int onoff) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci u8 *b; 6362306a36Sopenharmony_ci int ret; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci b = kmalloc(3, GFP_KERNEL); 6662306a36Sopenharmony_ci if (!b) 6762306a36Sopenharmony_ci return -ENOMEM; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci b[0] = DIBUSB_REQ_SET_IOCTL; 7062306a36Sopenharmony_ci b[1] = DIBUSB_IOCTL_CMD_POWER_MODE; 7162306a36Sopenharmony_ci b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci ret = dvb_usb_generic_write(d, b, 3); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci kfree(b); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci msleep(10); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci return ret; 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ciEXPORT_SYMBOL(dibusb_power_ctrl); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ciint dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci int ret; 8662306a36Sopenharmony_ci u8 *b; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci b = kmalloc(3, GFP_KERNEL); 8962306a36Sopenharmony_ci if (!b) 9062306a36Sopenharmony_ci return -ENOMEM; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0) 9362306a36Sopenharmony_ci goto ret; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci if (onoff) { 9662306a36Sopenharmony_ci b[0] = DIBUSB_REQ_SET_STREAMING_MODE; 9762306a36Sopenharmony_ci b[1] = 0x00; 9862306a36Sopenharmony_ci ret = dvb_usb_generic_write(adap->dev, b, 2); 9962306a36Sopenharmony_ci if (ret < 0) 10062306a36Sopenharmony_ci goto ret; 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci b[0] = DIBUSB_REQ_SET_IOCTL; 10462306a36Sopenharmony_ci b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM; 10562306a36Sopenharmony_ci ret = dvb_usb_generic_write(adap->dev, b, 3); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ciret: 10862306a36Sopenharmony_ci kfree(b); 10962306a36Sopenharmony_ci return ret; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ciEXPORT_SYMBOL(dibusb2_0_streaming_ctrl); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ciint dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci u8 *b; 11662306a36Sopenharmony_ci int ret; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci if (!onoff) 11962306a36Sopenharmony_ci return 0; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci b = kmalloc(3, GFP_KERNEL); 12262306a36Sopenharmony_ci if (!b) 12362306a36Sopenharmony_ci return -ENOMEM; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci b[0] = DIBUSB_REQ_SET_IOCTL; 12662306a36Sopenharmony_ci b[1] = DIBUSB_IOCTL_CMD_POWER_MODE; 12762306a36Sopenharmony_ci b[2] = DIBUSB_IOCTL_POWER_WAKEUP; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci ret = dvb_usb_generic_write(d, b, 3); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci kfree(b); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci return ret; 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ciEXPORT_SYMBOL(dibusb2_0_power_ctrl); 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cistatic int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr, 13862306a36Sopenharmony_ci u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) 13962306a36Sopenharmony_ci{ 14062306a36Sopenharmony_ci u8 *sndbuf; 14162306a36Sopenharmony_ci int ret, wo, len; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci /* write only ? */ 14462306a36Sopenharmony_ci wo = (rbuf == NULL || rlen == 0); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci len = 2 + wlen + (wo ? 0 : 2); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci sndbuf = kmalloc(MAX_XFER_SIZE, GFP_KERNEL); 14962306a36Sopenharmony_ci if (!sndbuf) 15062306a36Sopenharmony_ci return -ENOMEM; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci if (4 + wlen > MAX_XFER_SIZE) { 15362306a36Sopenharmony_ci warn("i2c wr: len=%d is too big!\n", wlen); 15462306a36Sopenharmony_ci ret = -EOPNOTSUPP; 15562306a36Sopenharmony_ci goto ret; 15662306a36Sopenharmony_ci } 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ; 15962306a36Sopenharmony_ci sndbuf[1] = (addr << 1) | (wo ? 0 : 1); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci memcpy(&sndbuf[2], wbuf, wlen); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci if (!wo) { 16462306a36Sopenharmony_ci sndbuf[wlen + 2] = (rlen >> 8) & 0xff; 16562306a36Sopenharmony_ci sndbuf[wlen + 3] = rlen & 0xff; 16662306a36Sopenharmony_ci } 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci ret = dvb_usb_generic_rw(d, sndbuf, len, rbuf, rlen, 0); 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ciret: 17162306a36Sopenharmony_ci kfree(sndbuf); 17262306a36Sopenharmony_ci return ret; 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci/* 17662306a36Sopenharmony_ci * I2C master xfer function 17762306a36Sopenharmony_ci */ 17862306a36Sopenharmony_cistatic int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci struct dvb_usb_device *d = i2c_get_adapdata(adap); 18162306a36Sopenharmony_ci int i; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 18462306a36Sopenharmony_ci return -EAGAIN; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci for (i = 0; i < num; i++) { 18762306a36Sopenharmony_ci /* write/read request */ 18862306a36Sopenharmony_ci if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0 18962306a36Sopenharmony_ci && (msg[i+1].flags & I2C_M_RD)) { 19062306a36Sopenharmony_ci if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len, 19162306a36Sopenharmony_ci msg[i+1].buf,msg[i+1].len) < 0) 19262306a36Sopenharmony_ci break; 19362306a36Sopenharmony_ci i++; 19462306a36Sopenharmony_ci } else if ((msg[i].flags & I2C_M_RD) == 0) { 19562306a36Sopenharmony_ci if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) 19662306a36Sopenharmony_ci break; 19762306a36Sopenharmony_ci } else if (msg[i].addr != 0x50) { 19862306a36Sopenharmony_ci /* 0x50 is the address of the eeprom - we need to protect it 19962306a36Sopenharmony_ci * from dibusb's bad i2c implementation: reads without 20062306a36Sopenharmony_ci * writing the offset before are forbidden */ 20162306a36Sopenharmony_ci if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0) 20262306a36Sopenharmony_ci break; 20362306a36Sopenharmony_ci } 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci mutex_unlock(&d->i2c_mutex); 20762306a36Sopenharmony_ci return i; 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cistatic u32 dibusb_i2c_func(struct i2c_adapter *adapter) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci return I2C_FUNC_I2C; 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistruct i2c_algorithm dibusb_i2c_algo = { 21662306a36Sopenharmony_ci .master_xfer = dibusb_i2c_xfer, 21762306a36Sopenharmony_ci .functionality = dibusb_i2c_func, 21862306a36Sopenharmony_ci}; 21962306a36Sopenharmony_ciEXPORT_SYMBOL(dibusb_i2c_algo); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ciint dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci u8 *buf; 22462306a36Sopenharmony_ci int rc; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci buf = kzalloc(2, GFP_KERNEL); 22762306a36Sopenharmony_ci if (!buf) 22862306a36Sopenharmony_ci return -ENOMEM; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci buf[0] = offs; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci rc = dibusb_i2c_msg(d, 0x50, &buf[0], 1, &buf[1], 1); 23362306a36Sopenharmony_ci *val = buf[1]; 23462306a36Sopenharmony_ci kfree(buf); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci return rc; 23762306a36Sopenharmony_ci} 23862306a36Sopenharmony_ciEXPORT_SYMBOL(dibusb_read_eeprom_byte); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci/* 24162306a36Sopenharmony_ci * common remote control stuff 24262306a36Sopenharmony_ci */ 24362306a36Sopenharmony_cistruct rc_map_table rc_map_dibusb_table[] = { 24462306a36Sopenharmony_ci /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */ 24562306a36Sopenharmony_ci { 0x0016, KEY_POWER }, 24662306a36Sopenharmony_ci { 0x0010, KEY_MUTE }, 24762306a36Sopenharmony_ci { 0x0003, KEY_1 }, 24862306a36Sopenharmony_ci { 0x0001, KEY_2 }, 24962306a36Sopenharmony_ci { 0x0006, KEY_3 }, 25062306a36Sopenharmony_ci { 0x0009, KEY_4 }, 25162306a36Sopenharmony_ci { 0x001d, KEY_5 }, 25262306a36Sopenharmony_ci { 0x001f, KEY_6 }, 25362306a36Sopenharmony_ci { 0x000d, KEY_7 }, 25462306a36Sopenharmony_ci { 0x0019, KEY_8 }, 25562306a36Sopenharmony_ci { 0x001b, KEY_9 }, 25662306a36Sopenharmony_ci { 0x0015, KEY_0 }, 25762306a36Sopenharmony_ci { 0x0005, KEY_CHANNELUP }, 25862306a36Sopenharmony_ci { 0x0002, KEY_CHANNELDOWN }, 25962306a36Sopenharmony_ci { 0x001e, KEY_VOLUMEUP }, 26062306a36Sopenharmony_ci { 0x000a, KEY_VOLUMEDOWN }, 26162306a36Sopenharmony_ci { 0x0011, KEY_RECORD }, 26262306a36Sopenharmony_ci { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */ 26362306a36Sopenharmony_ci { 0x0014, KEY_PLAY }, 26462306a36Sopenharmony_ci { 0x001a, KEY_STOP }, 26562306a36Sopenharmony_ci { 0x0040, KEY_REWIND }, 26662306a36Sopenharmony_ci { 0x0012, KEY_FASTFORWARD }, 26762306a36Sopenharmony_ci { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */ 26862306a36Sopenharmony_ci { 0x004c, KEY_PAUSE }, 26962306a36Sopenharmony_ci { 0x004d, KEY_SCREEN }, /* Full screen mode. */ 27062306a36Sopenharmony_ci { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ 27162306a36Sopenharmony_ci /* additional keys TwinHan VisionPlus, the Artec seemingly not have */ 27262306a36Sopenharmony_ci { 0x000c, KEY_CANCEL }, /* Cancel */ 27362306a36Sopenharmony_ci { 0x001c, KEY_EPG }, /* EPG */ 27462306a36Sopenharmony_ci { 0x0000, KEY_TAB }, /* Tab */ 27562306a36Sopenharmony_ci { 0x0048, KEY_INFO }, /* Preview */ 27662306a36Sopenharmony_ci { 0x0004, KEY_LIST }, /* RecordList */ 27762306a36Sopenharmony_ci { 0x000f, KEY_TEXT }, /* Teletext */ 27862306a36Sopenharmony_ci /* Key codes for the KWorld/ADSTech/JetWay remote. */ 27962306a36Sopenharmony_ci { 0x8612, KEY_POWER }, 28062306a36Sopenharmony_ci { 0x860f, KEY_SELECT }, /* source */ 28162306a36Sopenharmony_ci { 0x860c, KEY_UNKNOWN }, /* scan */ 28262306a36Sopenharmony_ci { 0x860b, KEY_EPG }, 28362306a36Sopenharmony_ci { 0x8610, KEY_MUTE }, 28462306a36Sopenharmony_ci { 0x8601, KEY_1 }, 28562306a36Sopenharmony_ci { 0x8602, KEY_2 }, 28662306a36Sopenharmony_ci { 0x8603, KEY_3 }, 28762306a36Sopenharmony_ci { 0x8604, KEY_4 }, 28862306a36Sopenharmony_ci { 0x8605, KEY_5 }, 28962306a36Sopenharmony_ci { 0x8606, KEY_6 }, 29062306a36Sopenharmony_ci { 0x8607, KEY_7 }, 29162306a36Sopenharmony_ci { 0x8608, KEY_8 }, 29262306a36Sopenharmony_ci { 0x8609, KEY_9 }, 29362306a36Sopenharmony_ci { 0x860a, KEY_0 }, 29462306a36Sopenharmony_ci { 0x8618, KEY_ZOOM }, 29562306a36Sopenharmony_ci { 0x861c, KEY_UNKNOWN }, /* preview */ 29662306a36Sopenharmony_ci { 0x8613, KEY_UNKNOWN }, /* snap */ 29762306a36Sopenharmony_ci { 0x8600, KEY_UNDO }, 29862306a36Sopenharmony_ci { 0x861d, KEY_RECORD }, 29962306a36Sopenharmony_ci { 0x860d, KEY_STOP }, 30062306a36Sopenharmony_ci { 0x860e, KEY_PAUSE }, 30162306a36Sopenharmony_ci { 0x8616, KEY_PLAY }, 30262306a36Sopenharmony_ci { 0x8611, KEY_BACK }, 30362306a36Sopenharmony_ci { 0x8619, KEY_FORWARD }, 30462306a36Sopenharmony_ci { 0x8614, KEY_UNKNOWN }, /* pip */ 30562306a36Sopenharmony_ci { 0x8615, KEY_ESC }, 30662306a36Sopenharmony_ci { 0x861a, KEY_UP }, 30762306a36Sopenharmony_ci { 0x861e, KEY_DOWN }, 30862306a36Sopenharmony_ci { 0x861f, KEY_LEFT }, 30962306a36Sopenharmony_ci { 0x861b, KEY_RIGHT }, 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci /* Key codes for the DiBcom MOD3000 remote. */ 31262306a36Sopenharmony_ci { 0x8000, KEY_MUTE }, 31362306a36Sopenharmony_ci { 0x8001, KEY_TEXT }, 31462306a36Sopenharmony_ci { 0x8002, KEY_HOME }, 31562306a36Sopenharmony_ci { 0x8003, KEY_POWER }, 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci { 0x8004, KEY_RED }, 31862306a36Sopenharmony_ci { 0x8005, KEY_GREEN }, 31962306a36Sopenharmony_ci { 0x8006, KEY_YELLOW }, 32062306a36Sopenharmony_ci { 0x8007, KEY_BLUE }, 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci { 0x8008, KEY_DVD }, 32362306a36Sopenharmony_ci { 0x8009, KEY_AUDIO }, 32462306a36Sopenharmony_ci { 0x800a, KEY_IMAGES }, /* Pictures */ 32562306a36Sopenharmony_ci { 0x800b, KEY_VIDEO }, 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci { 0x800c, KEY_BACK }, 32862306a36Sopenharmony_ci { 0x800d, KEY_UP }, 32962306a36Sopenharmony_ci { 0x800e, KEY_RADIO }, 33062306a36Sopenharmony_ci { 0x800f, KEY_EPG }, 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci { 0x8010, KEY_LEFT }, 33362306a36Sopenharmony_ci { 0x8011, KEY_OK }, 33462306a36Sopenharmony_ci { 0x8012, KEY_RIGHT }, 33562306a36Sopenharmony_ci { 0x8013, KEY_UNKNOWN }, /* SAP */ 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci { 0x8014, KEY_TV }, 33862306a36Sopenharmony_ci { 0x8015, KEY_DOWN }, 33962306a36Sopenharmony_ci { 0x8016, KEY_MENU }, /* DVD Menu */ 34062306a36Sopenharmony_ci { 0x8017, KEY_LAST }, 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci { 0x8018, KEY_RECORD }, 34362306a36Sopenharmony_ci { 0x8019, KEY_STOP }, 34462306a36Sopenharmony_ci { 0x801a, KEY_PAUSE }, 34562306a36Sopenharmony_ci { 0x801b, KEY_PLAY }, 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci { 0x801c, KEY_PREVIOUS }, 34862306a36Sopenharmony_ci { 0x801d, KEY_REWIND }, 34962306a36Sopenharmony_ci { 0x801e, KEY_FASTFORWARD }, 35062306a36Sopenharmony_ci { 0x801f, KEY_NEXT}, 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci { 0x8040, KEY_1 }, 35362306a36Sopenharmony_ci { 0x8041, KEY_2 }, 35462306a36Sopenharmony_ci { 0x8042, KEY_3 }, 35562306a36Sopenharmony_ci { 0x8043, KEY_CHANNELUP }, 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci { 0x8044, KEY_4 }, 35862306a36Sopenharmony_ci { 0x8045, KEY_5 }, 35962306a36Sopenharmony_ci { 0x8046, KEY_6 }, 36062306a36Sopenharmony_ci { 0x8047, KEY_CHANNELDOWN }, 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci { 0x8048, KEY_7 }, 36362306a36Sopenharmony_ci { 0x8049, KEY_8 }, 36462306a36Sopenharmony_ci { 0x804a, KEY_9 }, 36562306a36Sopenharmony_ci { 0x804b, KEY_VOLUMEUP }, 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci { 0x804c, KEY_CLEAR }, 36862306a36Sopenharmony_ci { 0x804d, KEY_0 }, 36962306a36Sopenharmony_ci { 0x804e, KEY_ENTER }, 37062306a36Sopenharmony_ci { 0x804f, KEY_VOLUMEDOWN }, 37162306a36Sopenharmony_ci}; 37262306a36Sopenharmony_ciEXPORT_SYMBOL(rc_map_dibusb_table); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ciint dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 37562306a36Sopenharmony_ci{ 37662306a36Sopenharmony_ci u8 *buf; 37762306a36Sopenharmony_ci int ret; 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci buf = kmalloc(5, GFP_KERNEL); 38062306a36Sopenharmony_ci if (!buf) 38162306a36Sopenharmony_ci return -ENOMEM; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci buf[0] = DIBUSB_REQ_POLL_REMOTE; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci ret = dvb_usb_generic_rw(d, buf, 1, buf, 5, 0); 38662306a36Sopenharmony_ci if (ret < 0) 38762306a36Sopenharmony_ci goto ret; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci dvb_usb_nec_rc_key_to_event(d, buf, event, state); 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci if (buf[0] != 0) 39262306a36Sopenharmony_ci deb_info("key: %*ph\n", 5, buf); 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ciret: 39562306a36Sopenharmony_ci kfree(buf); 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci return ret; 39862306a36Sopenharmony_ci} 39962306a36Sopenharmony_ciEXPORT_SYMBOL(dibusb_rc_query); 400