mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (505 commits) [media] af9015: Fix max I2C message size when used with tda18271 [media] IR: initialize ir_raw_event in few more drivers [media] Guard a divide in v4l1 compat layer [media] imon: fix nomouse modprobe option [media] imon: remove redundant change_protocol call [media] imon: fix my egregious brown paper bag w/rdev/idev split [media] cafe_ccic: Configure ov7670 correctly [media] ov7670: allow configuration of image size, clock speed, and I/O method [media] af9015: support for DigitalNow TinyTwin v3 [1f4d:9016] [media] af9015: map DigitalNow TinyTwin v2 remote [media] DigitalNow TinyTwin remote controller [media] af9015: RC fixes and improvements videodev2.h.xml: Update to reflect the latest changes at videodev2.h [media] v4l: document new Bayer and monochrome pixel formats [media] DocBook/v4l: Add missing formats used on gspca cpia1 and sn9c2028 [media] firedtv: add parameter to fake ca_system_ids in CA_INFO [media] tm6000: fix a macro coding style issue tm6000: Remove some ugly debug code [media] Nova-S-Plus audio line input [media] [RFC,1/1] V4L2: Use new CAP bits in existing RDS capable drivers ...
This commit is contained in:
commit
0851668fdd
531 changed files with 41145 additions and 13099 deletions
|
|
@ -79,6 +79,18 @@ config IR_SONY_DECODER
|
|||
Enable this option if you have an infrared remote control which
|
||||
uses the Sony protocol, and you need software decoding support.
|
||||
|
||||
config IR_RC5_SZ_DECODER
|
||||
tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol"
|
||||
depends on IR_CORE
|
||||
select BITREVERSE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have IR with RC-5 (streamzap) protocol,
|
||||
and if the IR is decoded in software. (The Streamzap PC Remote
|
||||
uses an IR protocol that is almost standard RC-5, but not quite,
|
||||
as it uses an additional bit).
|
||||
|
||||
config IR_LIRC_CODEC
|
||||
tristate "Enable IR to LIRC bridge"
|
||||
depends on IR_CORE
|
||||
|
|
@ -89,6 +101,20 @@ config IR_LIRC_CODEC
|
|||
Enable this option to pass raw IR to and from userspace via
|
||||
the LIRC interface.
|
||||
|
||||
config IR_ENE
|
||||
tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)"
|
||||
depends on PNP
|
||||
depends on IR_CORE
|
||||
---help---
|
||||
Say Y here to enable support for integrated infrared receiver
|
||||
/transceiver made by ENE.
|
||||
|
||||
You can see if you have it by looking at lspnp output.
|
||||
Output should include ENE0100 ENE0200 or something similar.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ene_ir.
|
||||
|
||||
config IR_IMON
|
||||
tristate "SoundGraph iMON Receiver and Display"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
|
|
@ -113,19 +139,18 @@ config IR_MCEUSB
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called mceusb.
|
||||
|
||||
config IR_ENE
|
||||
tristate "ENE eHome Receiver/Transciever (pnp id: ENE0100/ENE02xxx)"
|
||||
config IR_NUVOTON
|
||||
tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
|
||||
depends on PNP
|
||||
depends on IR_CORE
|
||||
---help---
|
||||
Say Y here to enable support for integrated infrared receiver
|
||||
/transciever made by ENE.
|
||||
|
||||
You can see if you have it by looking at lspnp output.
|
||||
Output should include ENE0100 ENE0200 or something similiar.
|
||||
/transciever made by Nuvoton (formerly Winbond). This chip is
|
||||
found in the ASRock ION 330HT, as well as assorted Intel
|
||||
DP55-series motherboards (and of course, possibly others).
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ene_ir.
|
||||
module will be called nuvoton-cir.
|
||||
|
||||
config IR_STREAMZAP
|
||||
tristate "Streamzap PC Remote IR Receiver"
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@ obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
|
|||
obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
|
||||
obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
|
||||
obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
|
||||
obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
|
||||
obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
|
||||
|
||||
# stand-alone IR receivers/transmitters
|
||||
obj-$(CONFIG_IR_IMON) += imon.o
|
||||
obj-$(CONFIG_IR_MCEUSB) += mceusb.o
|
||||
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
|
||||
obj-$(CONFIG_IR_ENE) += ene_ir.o
|
||||
obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* driver for ENE KB3926 B/C/D CIR (also known as ENE0XXX)
|
||||
* driver for ENE KB3926 B/C/D/E/F CIR (also known as ENE0XXX)
|
||||
*
|
||||
* Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com>
|
||||
*
|
||||
|
|
@ -26,43 +26,50 @@
|
|||
#define ENE_ADDR_HI 1 /* hi byte of register address */
|
||||
#define ENE_ADDR_LO 2 /* low byte of register address */
|
||||
#define ENE_IO 3 /* read/write window */
|
||||
#define ENE_MAX_IO 4
|
||||
#define ENE_IO_SIZE 4
|
||||
|
||||
/* 8 bytes of samples, divided in 2 halfs*/
|
||||
#define ENE_SAMPLE_BUFFER 0xF8F0 /* regular sample buffer */
|
||||
#define ENE_SAMPLE_SPC_MASK 0x80 /* sample is space */
|
||||
#define ENE_SAMPLE_VALUE_MASK 0x7F
|
||||
#define ENE_SAMPLE_OVERFLOW 0x7F
|
||||
#define ENE_SAMPLES_SIZE 4
|
||||
/* 8 bytes of samples, divided in 2 packets*/
|
||||
#define ENE_FW_SAMPLE_BUFFER 0xF8F0 /* sample buffer */
|
||||
#define ENE_FW_SAMPLE_SPACE 0x80 /* sample is space */
|
||||
#define ENE_FW_PACKET_SIZE 4
|
||||
|
||||
/* fan input sample buffer */
|
||||
#define ENE_SAMPLE_BUFFER_FAN 0xF8FB /* this buffer holds high byte of */
|
||||
/* each sample of normal buffer */
|
||||
#define ENE_FAN_SMPL_PULS_MSK 0x8000 /* this bit of combined sample */
|
||||
/* if set, says that sample is pulse */
|
||||
#define ENE_FAN_VALUE_MASK 0x0FFF /* mask for valid bits of the value */
|
||||
|
||||
/* first firmware register */
|
||||
#define ENE_FW1 0xF8F8
|
||||
/* first firmware flag register */
|
||||
#define ENE_FW1 0xF8F8 /* flagr */
|
||||
#define ENE_FW1_ENABLE 0x01 /* enable fw processing */
|
||||
#define ENE_FW1_TXIRQ 0x02 /* TX interrupt pending */
|
||||
#define ENE_FW1_HAS_EXTRA_BUF 0x04 /* fw uses extra buffer*/
|
||||
#define ENE_FW1_EXTRA_BUF_HND 0x08 /* extra buffer handshake bit*/
|
||||
#define ENE_FW1_LED_ON 0x10 /* turn on a led */
|
||||
|
||||
#define ENE_FW1_WPATTERN 0x20 /* enable wake pattern */
|
||||
#define ENE_FW1_WAKE 0x40 /* enable wake from S3 */
|
||||
#define ENE_FW1_IRQ 0x80 /* enable interrupt */
|
||||
|
||||
/* second firmware register */
|
||||
#define ENE_FW2 0xF8F9
|
||||
#define ENE_FW2_BUF_HIGH 0x01 /* which half of the buffer to read */
|
||||
#define ENE_FW2_IRQ_CLR 0x04 /* clear this on IRQ */
|
||||
#define ENE_FW2_GP40_AS_LEARN 0x08 /* normal input is used as */
|
||||
/* learning input */
|
||||
#define ENE_FW2_FAN_AS_NRML_IN 0x40 /* fan is used as normal input */
|
||||
/* second firmware flag register */
|
||||
#define ENE_FW2 0xF8F9 /* flagw */
|
||||
#define ENE_FW2_BUF_WPTR 0x01 /* which half of the buffer to read */
|
||||
#define ENE_FW2_RXIRQ 0x04 /* RX IRQ pending*/
|
||||
#define ENE_FW2_GP0A 0x08 /* Use GPIO0A for demodulated input */
|
||||
#define ENE_FW2_EMMITER1_CONN 0x10 /* TX emmiter 1 connected */
|
||||
#define ENE_FW2_EMMITER2_CONN 0x20 /* TX emmiter 2 connected */
|
||||
|
||||
#define ENE_FW2_FAN_INPUT 0x40 /* fan input used for demodulated data*/
|
||||
#define ENE_FW2_LEARNING 0x80 /* hardware supports learning and TX */
|
||||
|
||||
/* firmware RX pointer for new style buffer */
|
||||
#define ENE_FW_RX_POINTER 0xF8FA
|
||||
|
||||
/* high parts of samples for fan input (8 samples)*/
|
||||
#define ENE_FW_SMPL_BUF_FAN 0xF8FB
|
||||
#define ENE_FW_SMPL_BUF_FAN_PLS 0x8000 /* combined sample is pulse */
|
||||
#define ENE_FW_SMPL_BUF_FAN_MSK 0x0FFF /* combined sample maximum value */
|
||||
#define ENE_FW_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */
|
||||
|
||||
/* transmitter ports */
|
||||
#define ENE_TX_PORT2 0xFC01 /* this enables one or both */
|
||||
#define ENE_TX_PORT2_EN 0x20 /* TX ports */
|
||||
#define ENE_TX_PORT1 0xFC08
|
||||
#define ENE_TX_PORT1_EN 0x02
|
||||
#define ENE_GPIOFS1 0xFC01
|
||||
#define ENE_GPIOFS1_GPIO0D 0x20 /* enable tx output on GPIO0D */
|
||||
#define ENE_GPIOFS8 0xFC08
|
||||
#define ENE_GPIOFS8_GPIO41 0x02 /* enable tx output on GPIO40 */
|
||||
|
||||
/* IRQ registers block (for revision B) */
|
||||
#define ENEB_IRQ 0xFD09 /* IRQ number */
|
||||
|
|
@ -70,98 +77,100 @@
|
|||
#define ENEB_IRQ_STATUS 0xFD80 /* irq status */
|
||||
#define ENEB_IRQ_STATUS_IR 0x20 /* IR irq */
|
||||
|
||||
/* fan as input settings - only if learning capable */
|
||||
/* fan as input settings */
|
||||
#define ENE_FAN_AS_IN1 0xFE30 /* fan init reg 1 */
|
||||
#define ENE_FAN_AS_IN1_EN 0xCD
|
||||
#define ENE_FAN_AS_IN2 0xFE31 /* fan init reg 2 */
|
||||
#define ENE_FAN_AS_IN2_EN 0x03
|
||||
#define ENE_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */
|
||||
|
||||
/* IRQ registers block (for revision C,D) */
|
||||
#define ENEC_IRQ 0xFE9B /* new irq settings register */
|
||||
#define ENEC_IRQ_MASK 0x0F /* irq number mask */
|
||||
#define ENEC_IRQ_UNK_EN 0x10 /* always enabled */
|
||||
#define ENEC_IRQ_STATUS 0x20 /* irq status and ACK */
|
||||
#define ENE_IRQ 0xFE9B /* new irq settings register */
|
||||
#define ENE_IRQ_MASK 0x0F /* irq number mask */
|
||||
#define ENE_IRQ_UNK_EN 0x10 /* always enabled */
|
||||
#define ENE_IRQ_STATUS 0x20 /* irq status and ACK */
|
||||
|
||||
/* CIR block settings */
|
||||
#define ENE_CIR_CONF1 0xFEC0
|
||||
#define ENE_CIR_CONF1_TX_CLEAR 0x01 /* clear that on revC */
|
||||
/* while transmitting */
|
||||
#define ENE_CIR_CONF1_RX_ON 0x07 /* normal receiver enabled */
|
||||
#define ENE_CIR_CONF1_LEARN1 0x08 /* enabled on learning mode */
|
||||
#define ENE_CIR_CONF1_TX_ON 0x30 /* enabled on transmit */
|
||||
#define ENE_CIR_CONF1_TX_CARR 0x80 /* send TX carrier or not */
|
||||
/* CIR Config register #1 */
|
||||
#define ENE_CIRCFG 0xFEC0
|
||||
#define ENE_CIRCFG_RX_EN 0x01 /* RX enable */
|
||||
#define ENE_CIRCFG_RX_IRQ 0x02 /* Enable hardware interrupt */
|
||||
#define ENE_CIRCFG_REV_POL 0x04 /* Input polarity reversed */
|
||||
#define ENE_CIRCFG_CARR_DEMOD 0x08 /* Enable carrier demodulator */
|
||||
|
||||
#define ENE_CIR_CONF2 0xFEC1 /* unknown setting = 0 */
|
||||
#define ENE_CIR_CONF2_LEARN2 0x10 /* set on enable learning */
|
||||
#define ENE_CIR_CONF2_GPIO40DIS 0x20 /* disable input via gpio40 */
|
||||
#define ENE_CIRCFG_TX_EN 0x10 /* TX enable */
|
||||
#define ENE_CIRCFG_TX_IRQ 0x20 /* Send interrupt on TX done */
|
||||
#define ENE_CIRCFG_TX_POL_REV 0x40 /* TX polarity reversed */
|
||||
#define ENE_CIRCFG_TX_CARR 0x80 /* send TX carrier or not */
|
||||
|
||||
#define ENE_CIR_SAMPLE_PERIOD 0xFEC8 /* sample period in us */
|
||||
#define ENE_CIR_SAMPLE_OVERFLOW 0x80 /* interrupt on overflows if set */
|
||||
/* CIR config register #2 */
|
||||
#define ENE_CIRCFG2 0xFEC1
|
||||
#define ENE_CIRCFG2_RLC 0x00
|
||||
#define ENE_CIRCFG2_RC5 0x01
|
||||
#define ENE_CIRCFG2_RC6 0x02
|
||||
#define ENE_CIRCFG2_NEC 0x03
|
||||
#define ENE_CIRCFG2_CARR_DETECT 0x10 /* Enable carrier detection */
|
||||
#define ENE_CIRCFG2_GPIO0A 0x20 /* Use GPIO0A instead of GPIO40 for input */
|
||||
#define ENE_CIRCFG2_FAST_SAMPL1 0x40 /* Fast leading pulse detection for RC6 */
|
||||
#define ENE_CIRCFG2_FAST_SAMPL2 0x80 /* Fast data detection for RC6 */
|
||||
|
||||
/* Knobs for protocol decoding - will document when/if will use them */
|
||||
#define ENE_CIRPF 0xFEC2
|
||||
#define ENE_CIRHIGH 0xFEC3
|
||||
#define ENE_CIRBIT 0xFEC4
|
||||
#define ENE_CIRSTART 0xFEC5
|
||||
#define ENE_CIRSTART2 0xFEC6
|
||||
|
||||
/* Actual register which contains RLC RX data - read by firmware */
|
||||
#define ENE_CIRDAT_IN 0xFEC7
|
||||
|
||||
|
||||
/* Two byte tx buffer */
|
||||
#define ENE_TX_INPUT1 0xFEC9
|
||||
#define ENE_TX_INPUT2 0xFECA
|
||||
#define ENE_TX_PULSE_MASK 0x80 /* Transmitted sample is pulse */
|
||||
#define ENE_TX_SMLP_MASK 0x7F
|
||||
#define ENE_TX_SMPL_PERIOD 50 /* transmit sample period - fixed */
|
||||
/* RLC configuration - sample period (1us resulution) + idle mode */
|
||||
#define ENE_CIRRLC_CFG 0xFEC8
|
||||
#define ENE_CIRRLC_CFG_OVERFLOW 0x80 /* interrupt on overflows if set */
|
||||
#define ENE_DEFAULT_SAMPLE_PERIOD 50
|
||||
|
||||
/* Two byte RLC TX buffer */
|
||||
#define ENE_CIRRLC_OUT0 0xFEC9
|
||||
#define ENE_CIRRLC_OUT1 0xFECA
|
||||
#define ENE_CIRRLC_OUT_PULSE 0x80 /* Transmitted sample is pulse */
|
||||
#define ENE_CIRRLC_OUT_MASK 0x7F
|
||||
|
||||
|
||||
/* Unknown TX setting - TX sample period ??? */
|
||||
#define ENE_TX_UNK1 0xFECB /* set to 0x63 */
|
||||
/* Carrier detect setting
|
||||
* Low nibble - number of carrier pulses to average
|
||||
* High nibble - number of initial carrier pulses to discard
|
||||
*/
|
||||
#define ENE_CIRCAR_PULS 0xFECB
|
||||
|
||||
/* Current received carrier period */
|
||||
#define ENE_RX_CARRIER 0xFECC /* RX period (500 ns) */
|
||||
#define ENE_RX_CARRIER_VALID 0x80 /* Register content valid */
|
||||
/* detected RX carrier period (resolution: 500 ns) */
|
||||
#define ENE_CIRCAR_PRD 0xFECC
|
||||
#define ENE_CIRCAR_PRD_VALID 0x80 /* data valid content valid */
|
||||
|
||||
/* detected RX carrier pulse width (resolution: 500 ns) */
|
||||
#define ENE_CIRCAR_HPRD 0xFECD
|
||||
|
||||
/* TX period (1/carrier) */
|
||||
#define ENE_TX_PERIOD 0xFECE /* TX period (500 ns) */
|
||||
#define ENE_TX_PERIOD_UNKBIT 0x80 /* This bit set on transmit*/
|
||||
#define ENE_TX_PERIOD_PULSE 0xFECF /* TX pulse period (500 ns)*/
|
||||
/* TX period (resolution: 500 ns, minimum 2)*/
|
||||
#define ENE_CIRMOD_PRD 0xFECE
|
||||
#define ENE_CIRMOD_PRD_POL 0x80 /* TX carrier polarity*/
|
||||
|
||||
#define ENE_CIRMOD_PRD_MAX 0x7F /* 15.87 kHz */
|
||||
#define ENE_CIRMOD_PRD_MIN 0x02 /* 1 Mhz */
|
||||
|
||||
/* TX pulse width (resolution: 500 ns)*/
|
||||
#define ENE_CIRMOD_HPRD 0xFECF
|
||||
|
||||
/* Hardware versions */
|
||||
#define ENE_HW_VERSION 0xFF00 /* hardware revision */
|
||||
#define ENE_ECHV 0xFF00 /* hardware revision */
|
||||
#define ENE_PLLFRH 0xFF16
|
||||
#define ENE_PLLFRL 0xFF17
|
||||
#define ENE_DEFAULT_PLL_FREQ 1000
|
||||
|
||||
#define ENE_HW_UNK 0xFF1D
|
||||
#define ENE_HW_UNK_CLR 0x04
|
||||
#define ENE_HW_VER_MAJOR 0xFF1E /* chip version */
|
||||
#define ENE_HW_VER_MINOR 0xFF1F
|
||||
#define ENE_ECSTS 0xFF1D
|
||||
#define ENE_ECSTS_RSRVD 0x04
|
||||
|
||||
#define ENE_ECVER_MAJOR 0xFF1E /* chip version */
|
||||
#define ENE_ECVER_MINOR 0xFF1F
|
||||
#define ENE_HW_VER_OLD 0xFD00
|
||||
|
||||
/* Normal/Learning carrier ranges - only valid if we have learning input*/
|
||||
/* TODO: test */
|
||||
#define ENE_NORMAL_RX_LOW 34
|
||||
#define ENE_NORMAL_RX_HI 38
|
||||
|
||||
/* Tx carrier range */
|
||||
/* Hardware might be able to do more, but this range is enough for
|
||||
all purposes */
|
||||
#define ENE_TX_PERIOD_MAX 32 /* corresponds to 29.4 kHz */
|
||||
#define ENE_TX_PERIOD_MIN 16 /* corrsponds to 62.5 kHz */
|
||||
|
||||
|
||||
|
||||
/* Minimal and maximal gaps */
|
||||
|
||||
/* Normal case:
|
||||
Minimal gap is 0x7F * sample period
|
||||
Maximum gap depends on hardware.
|
||||
For KB3926B, it is unlimited, for newer models its around
|
||||
250000, after which HW stops sending samples, and that is
|
||||
not possible to change */
|
||||
|
||||
/* Fan case:
|
||||
Both minimal and maximal gaps are same, and equal to 0xFFF * 0x61
|
||||
And there is nothing to change this setting
|
||||
*/
|
||||
|
||||
#define ENE_MAXGAP 250000
|
||||
#define ENE_MINGAP (127 * sample_period)
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#define ENE_DRIVER_NAME "ene_ir"
|
||||
|
|
@ -171,46 +180,60 @@
|
|||
|
||||
#define ENE_HW_B 1 /* 3926B */
|
||||
#define ENE_HW_C 2 /* 3926C */
|
||||
#define ENE_HW_D 3 /* 3926D */
|
||||
#define ENE_HW_D 3 /* 3926D or later */
|
||||
|
||||
#define ene_printk(level, text, ...) \
|
||||
printk(level ENE_DRIVER_NAME ": " text, ## __VA_ARGS__)
|
||||
printk(level ENE_DRIVER_NAME ": " text "\n", ## __VA_ARGS__)
|
||||
|
||||
#define ene_dbg(text, ...) \
|
||||
if (debug) \
|
||||
printk(KERN_DEBUG \
|
||||
ENE_DRIVER_NAME ": " text "\n" , ## __VA_ARGS__)
|
||||
#define ene_notice(text, ...) ene_printk(KERN_NOTICE, text, ## __VA_ARGS__)
|
||||
#define ene_warn(text, ...) ene_printk(KERN_WARNING, text, ## __VA_ARGS__)
|
||||
|
||||
#define ene_dbg_verbose(text, ...) \
|
||||
if (debug > 1) \
|
||||
printk(KERN_DEBUG \
|
||||
ENE_DRIVER_NAME ": " text "\n" , ## __VA_ARGS__)
|
||||
|
||||
#define __dbg(level, format, ...) \
|
||||
do { \
|
||||
if (debug >= level) \
|
||||
printk(KERN_DEBUG ENE_DRIVER_NAME \
|
||||
": " format "\n", ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define dbg(format, ...) __dbg(1, format, ## __VA_ARGS__)
|
||||
#define dbg_verbose(format, ...) __dbg(2, format, ## __VA_ARGS__)
|
||||
#define dbg_regs(format, ...) __dbg(3, format, ## __VA_ARGS__)
|
||||
|
||||
#define MS_TO_NS(msec) ((msec) * 1000)
|
||||
|
||||
struct ene_device {
|
||||
struct pnp_dev *pnp_dev;
|
||||
struct input_dev *idev;
|
||||
struct ir_dev_props *props;
|
||||
int in_use;
|
||||
|
||||
/* hw IO settings */
|
||||
unsigned long hw_io;
|
||||
long hw_io;
|
||||
int irq;
|
||||
spinlock_t hw_lock;
|
||||
|
||||
/* HW features */
|
||||
int hw_revision; /* hardware revision */
|
||||
bool hw_learning_and_tx_capable; /* learning capable */
|
||||
bool hw_gpio40_learning; /* gpio40 is learning */
|
||||
bool hw_fan_as_normal_input; /* fan input is used as */
|
||||
/* regular input */
|
||||
bool hw_use_gpio_0a; /* gpio0a is demodulated input*/
|
||||
bool hw_extra_buffer; /* hardware has 'extra buffer' */
|
||||
bool hw_fan_input; /* fan input is IR data source */
|
||||
bool hw_learning_and_tx_capable; /* learning & tx capable */
|
||||
int pll_freq;
|
||||
int buffer_len;
|
||||
|
||||
/* Extra RX buffer location */
|
||||
int extra_buf1_address;
|
||||
int extra_buf1_len;
|
||||
int extra_buf2_address;
|
||||
int extra_buf2_len;
|
||||
|
||||
/* HW state*/
|
||||
int rx_pointer; /* hw pointer to rx buffer */
|
||||
int r_pointer; /* pointer to next sample to read */
|
||||
int w_pointer; /* pointer to next sample hw will write */
|
||||
bool rx_fan_input_inuse; /* is fan input in use for rx*/
|
||||
int tx_reg; /* current reg used for TX */
|
||||
u8 saved_conf1; /* saved FEC0 reg */
|
||||
|
||||
/* TX sample handling */
|
||||
unsigned int tx_sample; /* current sample for TX */
|
||||
bool tx_sample_pulse; /* current sample is pulse */
|
||||
|
||||
|
|
@ -229,7 +252,11 @@ struct ene_device {
|
|||
int transmitter_mask;
|
||||
|
||||
/* RX settings */
|
||||
bool learning_enabled; /* learning input enabled */
|
||||
bool learning_mode_enabled; /* learning input enabled */
|
||||
bool carrier_detect_enabled; /* carrier detect enabled */
|
||||
int rx_period_adjust;
|
||||
bool rx_enabled;
|
||||
};
|
||||
|
||||
static int ene_irq_status(struct ene_device *dev);
|
||||
static void ene_rx_read_hw_pointer(struct ene_device *dev);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -17,6 +17,7 @@
|
|||
#define _IR_RAW_EVENT
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <media/ir-core.h>
|
||||
|
||||
struct ir_raw_handler {
|
||||
|
|
@ -33,6 +34,7 @@ struct ir_raw_handler {
|
|||
struct ir_raw_event_ctrl {
|
||||
struct list_head list; /* to keep track of raw clients */
|
||||
struct task_struct *thread;
|
||||
spinlock_t lock;
|
||||
struct kfifo kfifo; /* fifo for the pulse/space durations */
|
||||
ktime_t last_event; /* when last event occurred */
|
||||
enum raw_event_type last_type; /* last event type */
|
||||
|
|
@ -76,10 +78,22 @@ struct ir_raw_event_ctrl {
|
|||
bool first;
|
||||
bool toggle;
|
||||
} jvc;
|
||||
struct rc5_sz_dec {
|
||||
int state;
|
||||
u32 bits;
|
||||
unsigned count;
|
||||
unsigned wanted_bits;
|
||||
} rc5_sz;
|
||||
struct lirc_codec {
|
||||
struct ir_input_dev *ir_dev;
|
||||
struct lirc_driver *drv;
|
||||
int carrier_low;
|
||||
|
||||
ktime_t gap_start;
|
||||
u64 gap_duration;
|
||||
bool gap;
|
||||
bool send_timeout_reports;
|
||||
|
||||
} lirc;
|
||||
};
|
||||
|
||||
|
|
@ -107,13 +121,19 @@ static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration)
|
|||
ev->duration -= duration;
|
||||
}
|
||||
|
||||
/* Returns true if event is normal pulse/space event */
|
||||
static inline bool is_timing_event(struct ir_raw_event ev)
|
||||
{
|
||||
return !ev.carrier_report && !ev.reset;
|
||||
}
|
||||
|
||||
#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000)
|
||||
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
|
||||
#define IS_RESET(ev) (ev.duration == 0)
|
||||
/*
|
||||
* Routines from ir-sysfs.c - Meant to be called only internally inside
|
||||
* ir-core
|
||||
*/
|
||||
int ir_register_input(struct input_dev *input_dev);
|
||||
|
||||
int ir_register_class(struct input_dev *input_dev);
|
||||
void ir_unregister_class(struct input_dev *input_dev);
|
||||
|
|
|
|||
|
|
@ -50,8 +50,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
|||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
|
||||
return 0;
|
||||
|
||||
if (IS_RESET(ev)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
|
|||
* This routine is used to signal that a key has been released on the
|
||||
* remote control. It reports a keyup input event via input_report_key().
|
||||
*/
|
||||
static void ir_keyup(struct ir_input_dev *ir)
|
||||
void ir_keyup(struct ir_input_dev *ir)
|
||||
{
|
||||
if (!ir->keypressed)
|
||||
return;
|
||||
|
|
@ -445,6 +445,7 @@ static void ir_keyup(struct ir_input_dev *ir)
|
|||
input_sync(ir->input_dev);
|
||||
ir->keypressed = false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ir_keyup);
|
||||
|
||||
/**
|
||||
* ir_timer_keyup() - generates a keyup event after a timeout
|
||||
|
|
@ -640,6 +641,10 @@ int __ir_input_register(struct input_dev *input_dev,
|
|||
goto out_event;
|
||||
}
|
||||
|
||||
rc = ir_register_input(input_dev);
|
||||
if (rc < 0)
|
||||
goto out_event;
|
||||
|
||||
IR_dprintk(1, "Registered input device on %s for %s remote%s.\n",
|
||||
driver_name, rc_tab->name,
|
||||
(ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ?
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
|
||||
struct lirc_codec *lirc = &ir_dev->raw->lirc;
|
||||
int sample;
|
||||
|
||||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
|
||||
|
|
@ -40,21 +41,57 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
|||
if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
|
||||
return -EINVAL;
|
||||
|
||||
if (IS_RESET(ev))
|
||||
/* Packet start */
|
||||
if (ev.reset)
|
||||
return 0;
|
||||
|
||||
IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
|
||||
TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
/* Carrier reports */
|
||||
if (ev.carrier_report) {
|
||||
sample = LIRC_FREQUENCY(ev.carrier);
|
||||
|
||||
sample = ev.duration / 1000;
|
||||
if (ev.pulse)
|
||||
sample |= PULSE_BIT;
|
||||
/* Packet end */
|
||||
} else if (ev.timeout) {
|
||||
|
||||
if (lirc->gap)
|
||||
return 0;
|
||||
|
||||
lirc->gap_start = ktime_get();
|
||||
lirc->gap = true;
|
||||
lirc->gap_duration = ev.duration;
|
||||
|
||||
if (!lirc->send_timeout_reports)
|
||||
return 0;
|
||||
|
||||
sample = LIRC_TIMEOUT(ev.duration / 1000);
|
||||
|
||||
/* Normal sample */
|
||||
} else {
|
||||
|
||||
if (lirc->gap) {
|
||||
int gap_sample;
|
||||
|
||||
lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
|
||||
lirc->gap_start));
|
||||
|
||||
/* Convert to ms and cap by LIRC_VALUE_MASK */
|
||||
do_div(lirc->gap_duration, 1000);
|
||||
lirc->gap_duration = min(lirc->gap_duration,
|
||||
(u64)LIRC_VALUE_MASK);
|
||||
|
||||
gap_sample = LIRC_SPACE(lirc->gap_duration);
|
||||
lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
|
||||
(unsigned char *) &gap_sample);
|
||||
lirc->gap = false;
|
||||
}
|
||||
|
||||
sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
|
||||
LIRC_SPACE(ev.duration / 1000);
|
||||
}
|
||||
|
||||
lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
|
||||
(unsigned char *) &sample);
|
||||
wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +139,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
|||
struct ir_input_dev *ir_dev;
|
||||
int ret = 0;
|
||||
void *drv_data;
|
||||
unsigned long val = 0;
|
||||
__u32 val = 0, tmp;
|
||||
|
||||
lirc = lirc_get_pdata(filep);
|
||||
if (!lirc)
|
||||
|
|
@ -115,7 +152,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
|||
drv_data = ir_dev->props->priv;
|
||||
|
||||
if (_IOC_DIR(cmd) & _IOC_WRITE) {
|
||||
ret = get_user(val, (unsigned long *)arg);
|
||||
ret = get_user(val, (__u32 *)arg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -130,22 +167,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
|||
case LIRC_SET_SEND_MODE:
|
||||
if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
|
||||
return -EINVAL;
|
||||
break;
|
||||
return 0;
|
||||
|
||||
/* TX settings */
|
||||
case LIRC_SET_TRANSMITTER_MASK:
|
||||
if (ir_dev->props->s_tx_mask)
|
||||
ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
|
||||
else
|
||||
if (!ir_dev->props->s_tx_mask)
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
||||
return ir_dev->props->s_tx_mask(drv_data, val);
|
||||
|
||||
case LIRC_SET_SEND_CARRIER:
|
||||
if (ir_dev->props->s_tx_carrier)
|
||||
ir_dev->props->s_tx_carrier(drv_data, (u32)val);
|
||||
else
|
||||
if (!ir_dev->props->s_tx_carrier)
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
||||
return ir_dev->props->s_tx_carrier(drv_data, val);
|
||||
|
||||
case LIRC_SET_SEND_DUTY_CYCLE:
|
||||
if (!ir_dev->props->s_tx_duty_cycle)
|
||||
|
|
@ -154,39 +189,42 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
|||
if (val <= 0 || val >= 100)
|
||||
return -EINVAL;
|
||||
|
||||
ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val);
|
||||
break;
|
||||
return ir_dev->props->s_tx_duty_cycle(drv_data, val);
|
||||
|
||||
/* RX settings */
|
||||
case LIRC_SET_REC_CARRIER:
|
||||
if (ir_dev->props->s_rx_carrier_range)
|
||||
ret = ir_dev->props->s_rx_carrier_range(
|
||||
ir_dev->props->priv,
|
||||
ir_dev->raw->lirc.carrier_low, val);
|
||||
else
|
||||
if (!ir_dev->props->s_rx_carrier_range)
|
||||
return -ENOSYS;
|
||||
|
||||
if (!ret)
|
||||
ir_dev->raw->lirc.carrier_low = 0;
|
||||
break;
|
||||
if (val <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
return ir_dev->props->s_rx_carrier_range(drv_data,
|
||||
ir_dev->raw->lirc.carrier_low, val);
|
||||
|
||||
case LIRC_SET_REC_CARRIER_RANGE:
|
||||
if (val >= 0)
|
||||
ir_dev->raw->lirc.carrier_low = val;
|
||||
break;
|
||||
if (val <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
ir_dev->raw->lirc.carrier_low = val;
|
||||
return 0;
|
||||
|
||||
case LIRC_GET_REC_RESOLUTION:
|
||||
val = ir_dev->props->rx_resolution;
|
||||
break;
|
||||
|
||||
case LIRC_SET_WIDEBAND_RECEIVER:
|
||||
if (ir_dev->props->s_learning_mode)
|
||||
return ir_dev->props->s_learning_mode(
|
||||
ir_dev->props->priv, !!val);
|
||||
else
|
||||
if (!ir_dev->props->s_learning_mode)
|
||||
return -ENOSYS;
|
||||
|
||||
return ir_dev->props->s_learning_mode(drv_data, !!val);
|
||||
|
||||
case LIRC_SET_MEASURE_CARRIER_MODE:
|
||||
if (!ir_dev->props->s_carrier_report)
|
||||
return -ENOSYS;
|
||||
|
||||
return ir_dev->props->s_carrier_report(drv_data, !!val);
|
||||
|
||||
/* Generic timeout support */
|
||||
case LIRC_GET_MIN_TIMEOUT:
|
||||
if (!ir_dev->props->max_timeout)
|
||||
|
|
@ -201,10 +239,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
|||
break;
|
||||
|
||||
case LIRC_SET_REC_TIMEOUT:
|
||||
if (val < ir_dev->props->min_timeout ||
|
||||
val > ir_dev->props->max_timeout)
|
||||
return -EINVAL;
|
||||
ir_dev->props->timeout = val * 1000;
|
||||
if (!ir_dev->props->max_timeout)
|
||||
return -ENOSYS;
|
||||
|
||||
tmp = val * 1000;
|
||||
|
||||
if (tmp < ir_dev->props->min_timeout ||
|
||||
tmp > ir_dev->props->max_timeout)
|
||||
return -EINVAL;
|
||||
|
||||
ir_dev->props->timeout = tmp;
|
||||
break;
|
||||
|
||||
case LIRC_SET_REC_TIMEOUT_REPORTS:
|
||||
lirc->send_timeout_reports = !!val;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -212,7 +260,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
|||
}
|
||||
|
||||
if (_IOC_DIR(cmd) & _IOC_READ)
|
||||
ret = put_user(val, (unsigned long *)arg);
|
||||
ret = put_user(val, (__u32 *)arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -231,6 +279,9 @@ static struct file_operations lirc_fops = {
|
|||
.owner = THIS_MODULE,
|
||||
.write = ir_lirc_transmit_ir,
|
||||
.unlocked_ioctl = ir_lirc_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = ir_lirc_ioctl,
|
||||
#endif
|
||||
.read = lirc_dev_fop_read,
|
||||
.poll = lirc_dev_fop_poll,
|
||||
.open = lirc_dev_fop_open,
|
||||
|
|
@ -278,6 +329,10 @@ static int ir_lirc_register(struct input_dev *input_dev)
|
|||
if (ir_dev->props->s_learning_mode)
|
||||
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
|
||||
|
||||
if (ir_dev->props->s_carrier_report)
|
||||
features |= LIRC_CAN_MEASURE_CARRIER;
|
||||
|
||||
|
||||
if (ir_dev->props->max_timeout)
|
||||
features |= LIRC_CAN_SET_REC_TIMEOUT;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,8 +54,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
|||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
|
||||
return 0;
|
||||
|
||||
if (IS_RESET(ev)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,22 +39,34 @@ static int ir_raw_event_thread(void *data)
|
|||
struct ir_raw_event ev;
|
||||
struct ir_raw_handler *handler;
|
||||
struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data;
|
||||
int retval;
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
try_to_freeze();
|
||||
|
||||
mutex_lock(&ir_raw_handler_lock);
|
||||
spin_lock_irq(&raw->lock);
|
||||
retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev));
|
||||
|
||||
while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
|
||||
list_for_each_entry(handler, &ir_raw_handler_list, list)
|
||||
handler->decode(raw->input_dev, ev);
|
||||
raw->prev_ev = ev;
|
||||
if (!retval) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
if (kthread_should_stop())
|
||||
set_current_state(TASK_RUNNING);
|
||||
|
||||
spin_unlock_irq(&raw->lock);
|
||||
schedule();
|
||||
continue;
|
||||
}
|
||||
|
||||
mutex_unlock(&ir_raw_handler_lock);
|
||||
spin_unlock_irq(&raw->lock);
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule();
|
||||
|
||||
BUG_ON(retval != sizeof(ev));
|
||||
|
||||
mutex_lock(&ir_raw_handler_lock);
|
||||
list_for_each_entry(handler, &ir_raw_handler_list, list)
|
||||
handler->decode(raw->input_dev, ev);
|
||||
raw->prev_ev = ev;
|
||||
mutex_unlock(&ir_raw_handler_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -77,7 +89,7 @@ int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
|
|||
if (!ir->raw)
|
||||
return -EINVAL;
|
||||
|
||||
IR_dprintk(2, "sample: (05%dus %s)\n",
|
||||
IR_dprintk(2, "sample: (%05dus %s)\n",
|
||||
TO_US(ev->duration), TO_STR(ev->pulse));
|
||||
|
||||
if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
|
||||
|
|
@ -162,7 +174,7 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
|
|||
if (ir->idle && !ev->pulse)
|
||||
return 0;
|
||||
else if (ir->idle)
|
||||
ir_raw_event_set_idle(input_dev, 0);
|
||||
ir_raw_event_set_idle(input_dev, false);
|
||||
|
||||
if (!raw->this_ev.duration) {
|
||||
raw->this_ev = *ev;
|
||||
|
|
@ -175,48 +187,35 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
|
|||
|
||||
/* Enter idle mode if nessesary */
|
||||
if (!ev->pulse && ir->props->timeout &&
|
||||
raw->this_ev.duration >= ir->props->timeout)
|
||||
ir_raw_event_set_idle(input_dev, 1);
|
||||
raw->this_ev.duration >= ir->props->timeout) {
|
||||
ir_raw_event_set_idle(input_dev, true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
|
||||
|
||||
void ir_raw_event_set_idle(struct input_dev *input_dev, int idle)
|
||||
/**
|
||||
* ir_raw_event_set_idle() - hint the ir core if device is receiving
|
||||
* IR data or not
|
||||
* @input_dev: the struct input_dev device descriptor
|
||||
* @idle: the hint value
|
||||
*/
|
||||
void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle)
|
||||
{
|
||||
struct ir_input_dev *ir = input_get_drvdata(input_dev);
|
||||
struct ir_raw_event_ctrl *raw = ir->raw;
|
||||
ktime_t now;
|
||||
u64 delta;
|
||||
|
||||
if (!ir->props)
|
||||
if (!ir->props || !ir->raw)
|
||||
return;
|
||||
|
||||
if (!ir->raw)
|
||||
goto out;
|
||||
IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
|
||||
|
||||
if (idle) {
|
||||
IR_dprintk(2, "enter idle mode\n");
|
||||
raw->last_event = ktime_get();
|
||||
} else {
|
||||
IR_dprintk(2, "exit idle mode\n");
|
||||
|
||||
now = ktime_get();
|
||||
delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
|
||||
|
||||
WARN_ON(raw->this_ev.pulse);
|
||||
|
||||
raw->this_ev.duration =
|
||||
min(raw->this_ev.duration + delta,
|
||||
(u64)IR_MAX_DURATION);
|
||||
|
||||
raw->this_ev.timeout = true;
|
||||
ir_raw_event_store(input_dev, &raw->this_ev);
|
||||
|
||||
if (raw->this_ev.duration == IR_MAX_DURATION)
|
||||
ir_raw_event_reset(input_dev);
|
||||
|
||||
raw->this_ev.duration = 0;
|
||||
init_ir_raw_event(&raw->this_ev);
|
||||
}
|
||||
out:
|
||||
|
||||
if (ir->props->s_idle)
|
||||
ir->props->s_idle(ir->props->priv, idle);
|
||||
ir->idle = idle;
|
||||
|
|
@ -232,11 +231,14 @@ EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
|
|||
void ir_raw_event_handle(struct input_dev *input_dev)
|
||||
{
|
||||
struct ir_input_dev *ir = input_get_drvdata(input_dev);
|
||||
unsigned long flags;
|
||||
|
||||
if (!ir->raw)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&ir->raw->lock, flags);
|
||||
wake_up_process(ir->raw->thread);
|
||||
spin_unlock_irqrestore(&ir->raw->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ir_raw_event_handle);
|
||||
|
||||
|
|
@ -275,6 +277,7 @@ int ir_raw_event_register(struct input_dev *input_dev)
|
|||
return rc;
|
||||
}
|
||||
|
||||
spin_lock_init(&ir->raw->lock);
|
||||
ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw,
|
||||
"rc%u", (unsigned int)ir->devno);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,8 +55,9 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
|||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
|
||||
return 0;
|
||||
|
||||
if (IS_RESET(ev)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
154
drivers/media/IR/ir-rc5-sz-decoder.c
Normal file
154
drivers/media/IR/ir-rc5-sz-decoder.c
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol
|
||||
*
|
||||
* Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code handles the 15 bit RC5-ish protocol used by the Streamzap
|
||||
* PC Remote.
|
||||
* It considers a carrier of 36 kHz, with a total of 15 bits, where
|
||||
* the first two bits are start bits, and a third one is a filing bit
|
||||
*/
|
||||
|
||||
#include "ir-core-priv.h"
|
||||
|
||||
#define RC5_SZ_NBITS 15
|
||||
#define RC5_UNIT 888888 /* ns */
|
||||
#define RC5_BIT_START (1 * RC5_UNIT)
|
||||
#define RC5_BIT_END (1 * RC5_UNIT)
|
||||
|
||||
enum rc5_sz_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_BIT_START,
|
||||
STATE_BIT_END,
|
||||
STATE_FINISHED,
|
||||
};
|
||||
|
||||
/**
|
||||
* ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
|
||||
* @input_dev: the struct input_dev descriptor of the device
|
||||
* @ev: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
|
||||
struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
|
||||
u8 toggle, command, system;
|
||||
u32 scancode;
|
||||
|
||||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
|
||||
goto out;
|
||||
|
||||
again:
|
||||
IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
|
||||
return 0;
|
||||
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
data->state = STATE_BIT_START;
|
||||
data->count = 1;
|
||||
data->wanted_bits = RC5_SZ_NBITS;
|
||||
decrease_duration(&ev, RC5_BIT_START);
|
||||
goto again;
|
||||
|
||||
case STATE_BIT_START:
|
||||
if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->bits <<= 1;
|
||||
if (!ev.pulse)
|
||||
data->bits |= 1;
|
||||
data->count++;
|
||||
data->state = STATE_BIT_END;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_END:
|
||||
if (!is_transition(&ev, &ir_dev->raw->prev_ev))
|
||||
break;
|
||||
|
||||
if (data->count == data->wanted_bits)
|
||||
data->state = STATE_FINISHED;
|
||||
else
|
||||
data->state = STATE_BIT_START;
|
||||
|
||||
decrease_duration(&ev, RC5_BIT_END);
|
||||
goto again;
|
||||
|
||||
case STATE_FINISHED:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
/* RC5-sz */
|
||||
command = (data->bits & 0x0003F) >> 0;
|
||||
system = (data->bits & 0x02FC0) >> 6;
|
||||
toggle = (data->bits & 0x01000) ? 1 : 0;
|
||||
scancode = system << 6 | command;
|
||||
|
||||
IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
|
||||
scancode, toggle);
|
||||
|
||||
ir_keydown(input_dev, scancode, toggle);
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
out:
|
||||
IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler rc5_sz_handler = {
|
||||
.protocols = IR_TYPE_RC5_SZ,
|
||||
.decode = ir_rc5_sz_decode,
|
||||
};
|
||||
|
||||
static int __init ir_rc5_sz_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&rc5_sz_handler);
|
||||
|
||||
printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_rc5_sz_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&rc5_sz_handler);
|
||||
}
|
||||
|
||||
module_init(ir_rc5_sz_decode_init);
|
||||
module_exit(ir_rc5_sz_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jarod Wilson <[email protected]>");
|
||||
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder");
|
||||
|
|
@ -85,8 +85,9 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
|||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
|
||||
return 0;
|
||||
|
||||
if (IS_RESET(ev)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
|
|||
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
|
||||
return 0;
|
||||
|
||||
if (IS_RESET(ev)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ static struct {
|
|||
{ IR_TYPE_RC6, "rc-6" },
|
||||
{ IR_TYPE_JVC, "jvc" },
|
||||
{ IR_TYPE_SONY, "sony" },
|
||||
{ IR_TYPE_RC5_SZ, "rc-5-sz" },
|
||||
{ IR_TYPE_LIRC, "lirc" },
|
||||
};
|
||||
|
||||
|
|
@ -67,6 +68,10 @@ static ssize_t show_protocols(struct device *d,
|
|||
char *tmp = buf;
|
||||
int i;
|
||||
|
||||
/* Device is being removed */
|
||||
if (!ir_dev)
|
||||
return -EINVAL;
|
||||
|
||||
if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
|
||||
enabled = ir_dev->rc_tab.ir_type;
|
||||
allowed = ir_dev->props->allowed_protos;
|
||||
|
|
@ -122,6 +127,10 @@ static ssize_t store_protocols(struct device *d,
|
|||
int rc, i, count = 0;
|
||||
unsigned long flags;
|
||||
|
||||
/* Device is being removed */
|
||||
if (!ir_dev)
|
||||
return -EINVAL;
|
||||
|
||||
if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
|
||||
type = ir_dev->rc_tab.ir_type;
|
||||
else if (ir_dev->raw)
|
||||
|
|
@ -256,8 +265,6 @@ static struct device_type rc_dev_type = {
|
|||
*/
|
||||
int ir_register_class(struct input_dev *input_dev)
|
||||
{
|
||||
int rc;
|
||||
const char *path;
|
||||
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
|
||||
int devno = find_first_zero_bit(&ir_core_dev_number,
|
||||
IRRCV_NUM_DEVICES);
|
||||
|
|
@ -266,17 +273,28 @@ int ir_register_class(struct input_dev *input_dev)
|
|||
return devno;
|
||||
|
||||
ir_dev->dev.type = &rc_dev_type;
|
||||
ir_dev->devno = devno;
|
||||
|
||||
ir_dev->dev.class = &ir_input_class;
|
||||
ir_dev->dev.parent = input_dev->dev.parent;
|
||||
input_dev->dev.parent = &ir_dev->dev;
|
||||
dev_set_name(&ir_dev->dev, "rc%d", devno);
|
||||
dev_set_drvdata(&ir_dev->dev, ir_dev);
|
||||
rc = device_register(&ir_dev->dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
return device_register(&ir_dev->dev);
|
||||
};
|
||||
|
||||
/**
|
||||
* ir_register_input - registers ir input device with input subsystem
|
||||
* @input_dev: the struct input_dev descriptor of the device
|
||||
*/
|
||||
|
||||
int ir_register_input(struct input_dev *input_dev)
|
||||
{
|
||||
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
|
||||
int rc;
|
||||
const char *path;
|
||||
|
||||
|
||||
input_dev->dev.parent = &ir_dev->dev;
|
||||
rc = input_register_device(input_dev);
|
||||
if (rc < 0) {
|
||||
device_del(&ir_dev->dev);
|
||||
|
|
@ -292,11 +310,9 @@ int ir_register_class(struct input_dev *input_dev)
|
|||
path ? path : "N/A");
|
||||
kfree(path);
|
||||
|
||||
ir_dev->devno = devno;
|
||||
set_bit(devno, &ir_core_dev_number);
|
||||
|
||||
set_bit(ir_dev->devno, &ir_core_dev_number);
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* ir_unregister_class() - removes the sysfs for sysfs for
|
||||
|
|
@ -309,6 +325,7 @@ void ir_unregister_class(struct input_dev *input_dev)
|
|||
{
|
||||
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
|
||||
|
||||
input_set_drvdata(input_dev, NULL);
|
||||
clear_bit(ir_dev->devno, &ir_core_dev_number);
|
||||
input_unregister_device(input_dev);
|
||||
device_del(&ir_dev->dev);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
|
||||
rc-alink-dtu-m.o \
|
||||
rc-anysee.o \
|
||||
rc-apac-viewcomp.o \
|
||||
rc-asus-pc39.o \
|
||||
rc-ati-tv-wonder-hd-600.o \
|
||||
|
|
@ -8,7 +10,9 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
|
|||
rc-avermedia-dvbt.o \
|
||||
rc-avermedia-m135a.o \
|
||||
rc-avermedia-m733a-rm-k6.o \
|
||||
rc-avermedia-rm-ks.o \
|
||||
rc-avertv-303.o \
|
||||
rc-azurewave-ad-tu700.o \
|
||||
rc-behold.o \
|
||||
rc-behold-columbus.o \
|
||||
rc-budget-ci-old.o \
|
||||
|
|
@ -16,6 +20,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
|
|||
rc-cinergy.o \
|
||||
rc-dib0700-nec.o \
|
||||
rc-dib0700-rc5.o \
|
||||
rc-digitalnow-tinytwin.o \
|
||||
rc-digittrade.o \
|
||||
rc-dm1105-nec.o \
|
||||
rc-dntv-live-dvb-t.o \
|
||||
rc-dntv-live-dvbt-pro.o \
|
||||
|
|
@ -38,8 +44,12 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
|
|||
rc-kaiomy.o \
|
||||
rc-kworld-315u.o \
|
||||
rc-kworld-plus-tv-analog.o \
|
||||
rc-leadtek-y04g0051.o \
|
||||
rc-lirc.o \
|
||||
rc-lme2510.o \
|
||||
rc-manli.o \
|
||||
rc-msi-digivox-ii.o \
|
||||
rc-msi-digivox-iii.o \
|
||||
rc-msi-tvanywhere.o \
|
||||
rc-msi-tvanywhere-plus.o \
|
||||
rc-nebula.o \
|
||||
|
|
@ -58,14 +68,18 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
|
|||
rc-purpletv.o \
|
||||
rc-pv951.o \
|
||||
rc-rc5-hauppauge-new.o \
|
||||
rc-rc5-streamzap.o \
|
||||
rc-rc5-tv.o \
|
||||
rc-rc6-mce.o \
|
||||
rc-real-audio-220-32-keys.o \
|
||||
rc-streamzap.o \
|
||||
rc-tbs-nec.o \
|
||||
rc-terratec-cinergy-xs.o \
|
||||
rc-terratec-slim.o \
|
||||
rc-tevii-nec.o \
|
||||
rc-total-media-in-hand.o \
|
||||
rc-trekstor.o \
|
||||
rc-tt-1500.o \
|
||||
rc-twinhan1027.o \
|
||||
rc-videomate-s350.o \
|
||||
rc-videomate-tv-pvr.o \
|
||||
rc-winfast.o \
|
||||
|
|
|
|||
68
drivers/media/IR/keymaps/rc-alink-dtu-m.c
Normal file
68
drivers/media/IR/keymaps/rc-alink-dtu-m.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* A-Link DTU(m) remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
/* A-Link DTU(m) slim remote, 6 rows, 3 columns. */
|
||||
static struct ir_scancode alink_dtu_m[] = {
|
||||
{ 0x0800, KEY_VOLUMEUP },
|
||||
{ 0x0801, KEY_1 },
|
||||
{ 0x0802, KEY_3 },
|
||||
{ 0x0803, KEY_7 },
|
||||
{ 0x0804, KEY_9 },
|
||||
{ 0x0805, KEY_NEW }, /* symbol: PIP */
|
||||
{ 0x0806, KEY_0 },
|
||||
{ 0x0807, KEY_CHANNEL }, /* JUMP */
|
||||
{ 0x080d, KEY_5 },
|
||||
{ 0x080f, KEY_2 },
|
||||
{ 0x0812, KEY_POWER2 },
|
||||
{ 0x0814, KEY_CHANNELUP },
|
||||
{ 0x0816, KEY_VOLUMEDOWN },
|
||||
{ 0x0818, KEY_6 },
|
||||
{ 0x081a, KEY_MUTE },
|
||||
{ 0x081b, KEY_8 },
|
||||
{ 0x081c, KEY_4 },
|
||||
{ 0x081d, KEY_CHANNELDOWN },
|
||||
};
|
||||
|
||||
static struct rc_keymap alink_dtu_m_map = {
|
||||
.map = {
|
||||
.scan = alink_dtu_m,
|
||||
.size = ARRAY_SIZE(alink_dtu_m),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_ALINK_DTU_M,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_alink_dtu_m(void)
|
||||
{
|
||||
return ir_register_map(&alink_dtu_m_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_alink_dtu_m(void)
|
||||
{
|
||||
ir_unregister_map(&alink_dtu_m_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_alink_dtu_m)
|
||||
module_exit(exit_rc_map_alink_dtu_m)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
93
drivers/media/IR/keymaps/rc-anysee.c
Normal file
93
drivers/media/IR/keymaps/rc-anysee.c
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Anysee remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct ir_scancode anysee[] = {
|
||||
{ 0x0800, KEY_0 },
|
||||
{ 0x0801, KEY_1 },
|
||||
{ 0x0802, KEY_2 },
|
||||
{ 0x0803, KEY_3 },
|
||||
{ 0x0804, KEY_4 },
|
||||
{ 0x0805, KEY_5 },
|
||||
{ 0x0806, KEY_6 },
|
||||
{ 0x0807, KEY_7 },
|
||||
{ 0x0808, KEY_8 },
|
||||
{ 0x0809, KEY_9 },
|
||||
{ 0x080a, KEY_POWER2 }, /* [red power button] */
|
||||
{ 0x080b, KEY_VIDEO }, /* [*] MODE */
|
||||
{ 0x080c, KEY_CHANNEL }, /* [symbol counterclockwise arrow] */
|
||||
{ 0x080d, KEY_NEXT }, /* [>>|] */
|
||||
{ 0x080e, KEY_MENU }, /* MENU */
|
||||
{ 0x080f, KEY_EPG }, /* [EPG] */
|
||||
{ 0x0810, KEY_CLEAR }, /* EXIT */
|
||||
{ 0x0811, KEY_CHANNELUP },
|
||||
{ 0x0812, KEY_VOLUMEDOWN },
|
||||
{ 0x0813, KEY_VOLUMEUP },
|
||||
{ 0x0814, KEY_CHANNELDOWN },
|
||||
{ 0x0815, KEY_OK },
|
||||
{ 0x0816, KEY_RADIO }, /* [symbol TV/radio] */
|
||||
{ 0x0817, KEY_INFO }, /* [i] */
|
||||
{ 0x0818, KEY_PREVIOUS }, /* [|<<] */
|
||||
{ 0x0819, KEY_FAVORITES }, /* FAV. */
|
||||
{ 0x081a, KEY_SUBTITLE }, /* Subtitle */
|
||||
{ 0x081b, KEY_CAMERA }, /* [symbol camera] */
|
||||
{ 0x081c, KEY_YELLOW },
|
||||
{ 0x081d, KEY_RED },
|
||||
{ 0x081e, KEY_LANGUAGE }, /* [symbol Second Audio Program] */
|
||||
{ 0x081f, KEY_GREEN },
|
||||
{ 0x0820, KEY_SLEEP }, /* Sleep */
|
||||
{ 0x0821, KEY_SCREEN }, /* 16:9 / 4:3 */
|
||||
{ 0x0822, KEY_ZOOM }, /* SIZE */
|
||||
{ 0x0824, KEY_FN }, /* [F1] */
|
||||
{ 0x0825, KEY_FN }, /* [F2] */
|
||||
{ 0x0842, KEY_MUTE }, /* symbol mute */
|
||||
{ 0x0844, KEY_BLUE },
|
||||
{ 0x0847, KEY_TEXT }, /* TEXT */
|
||||
{ 0x0848, KEY_STOP },
|
||||
{ 0x0849, KEY_RECORD },
|
||||
{ 0x0850, KEY_PLAY },
|
||||
{ 0x0851, KEY_PAUSE },
|
||||
};
|
||||
|
||||
static struct rc_keymap anysee_map = {
|
||||
.map = {
|
||||
.scan = anysee,
|
||||
.size = ARRAY_SIZE(anysee),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_ANYSEE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_anysee(void)
|
||||
{
|
||||
return ir_register_map(&anysee_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_anysee(void)
|
||||
{
|
||||
ir_unregister_map(&anysee_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_anysee)
|
||||
module_exit(exit_rc_map_anysee)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
|
|
@ -20,56 +20,56 @@
|
|||
|
||||
static struct ir_scancode asus_pc39[] = {
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x15, KEY_0 },
|
||||
{ 0x29, KEY_1 },
|
||||
{ 0x2d, KEY_2 },
|
||||
{ 0x2b, KEY_3 },
|
||||
{ 0x09, KEY_4 },
|
||||
{ 0x0d, KEY_5 },
|
||||
{ 0x0b, KEY_6 },
|
||||
{ 0x31, KEY_7 },
|
||||
{ 0x35, KEY_8 },
|
||||
{ 0x33, KEY_9 },
|
||||
{ 0x082a, KEY_0 },
|
||||
{ 0x0816, KEY_1 },
|
||||
{ 0x0812, KEY_2 },
|
||||
{ 0x0814, KEY_3 },
|
||||
{ 0x0836, KEY_4 },
|
||||
{ 0x0832, KEY_5 },
|
||||
{ 0x0834, KEY_6 },
|
||||
{ 0x080e, KEY_7 },
|
||||
{ 0x080a, KEY_8 },
|
||||
{ 0x080c, KEY_9 },
|
||||
|
||||
{ 0x3e, KEY_RADIO }, /* radio */
|
||||
{ 0x03, KEY_MENU }, /* dvd/menu */
|
||||
{ 0x2a, KEY_VOLUMEUP },
|
||||
{ 0x19, KEY_VOLUMEDOWN },
|
||||
{ 0x37, KEY_UP },
|
||||
{ 0x3b, KEY_DOWN },
|
||||
{ 0x27, KEY_LEFT },
|
||||
{ 0x2f, KEY_RIGHT },
|
||||
{ 0x25, KEY_VIDEO }, /* video */
|
||||
{ 0x39, KEY_AUDIO }, /* music */
|
||||
{ 0x0801, KEY_RADIO }, /* radio */
|
||||
{ 0x083c, KEY_MENU }, /* dvd/menu */
|
||||
{ 0x0815, KEY_VOLUMEUP },
|
||||
{ 0x0826, KEY_VOLUMEDOWN },
|
||||
{ 0x0808, KEY_UP },
|
||||
{ 0x0804, KEY_DOWN },
|
||||
{ 0x0818, KEY_LEFT },
|
||||
{ 0x0810, KEY_RIGHT },
|
||||
{ 0x081a, KEY_VIDEO }, /* video */
|
||||
{ 0x0806, KEY_AUDIO }, /* music */
|
||||
|
||||
{ 0x21, KEY_TV }, /* tv */
|
||||
{ 0x1d, KEY_EXIT }, /* back */
|
||||
{ 0x0a, KEY_CHANNELUP }, /* channel / program + */
|
||||
{ 0x1b, KEY_CHANNELDOWN }, /* channel / program - */
|
||||
{ 0x1a, KEY_ENTER }, /* enter */
|
||||
{ 0x081e, KEY_TV }, /* tv */
|
||||
{ 0x0822, KEY_EXIT }, /* back */
|
||||
{ 0x0835, KEY_CHANNELUP }, /* channel / program + */
|
||||
{ 0x0824, KEY_CHANNELDOWN }, /* channel / program - */
|
||||
{ 0x0825, KEY_ENTER }, /* enter */
|
||||
|
||||
{ 0x06, KEY_PAUSE }, /* play/pause */
|
||||
{ 0x1e, KEY_PREVIOUS }, /* rew */
|
||||
{ 0x26, KEY_NEXT }, /* forward */
|
||||
{ 0x0e, KEY_REWIND }, /* backward << */
|
||||
{ 0x3a, KEY_FASTFORWARD }, /* forward >> */
|
||||
{ 0x36, KEY_STOP },
|
||||
{ 0x2e, KEY_RECORD }, /* recording */
|
||||
{ 0x16, KEY_POWER }, /* the button that reads "close" */
|
||||
{ 0x0839, KEY_PAUSE }, /* play/pause */
|
||||
{ 0x0821, KEY_PREVIOUS }, /* rew */
|
||||
{ 0x0819, KEY_NEXT }, /* forward */
|
||||
{ 0x0831, KEY_REWIND }, /* backward << */
|
||||
{ 0x0805, KEY_FASTFORWARD }, /* forward >> */
|
||||
{ 0x0809, KEY_STOP },
|
||||
{ 0x0811, KEY_RECORD }, /* recording */
|
||||
{ 0x0829, KEY_POWER }, /* the button that reads "close" */
|
||||
|
||||
{ 0x11, KEY_ZOOM }, /* full screen */
|
||||
{ 0x13, KEY_MACRO }, /* recall */
|
||||
{ 0x23, KEY_HOME }, /* home */
|
||||
{ 0x05, KEY_PVR }, /* picture */
|
||||
{ 0x3d, KEY_MUTE }, /* mute */
|
||||
{ 0x01, KEY_DVD }, /* dvd */
|
||||
{ 0x082e, KEY_ZOOM }, /* full screen */
|
||||
{ 0x082c, KEY_MACRO }, /* recall */
|
||||
{ 0x081c, KEY_HOME }, /* home */
|
||||
{ 0x083a, KEY_PVR }, /* picture */
|
||||
{ 0x0802, KEY_MUTE }, /* mute */
|
||||
{ 0x083e, KEY_DVD }, /* dvd */
|
||||
};
|
||||
|
||||
static struct rc_keymap asus_pc39_map = {
|
||||
.map = {
|
||||
.scan = asus_pc39,
|
||||
.size = ARRAY_SIZE(asus_pc39),
|
||||
.ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.ir_type = IR_TYPE_RC5,
|
||||
.name = RC_MAP_ASUS_PC39,
|
||||
}
|
||||
};
|
||||
|
|
|
|||
79
drivers/media/IR/keymaps/rc-avermedia-rm-ks.c
Normal file
79
drivers/media/IR/keymaps/rc-avermedia-rm-ks.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* AverMedia RM-KS remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
/* Initial keytable is from Jose Alberto Reguero <[email protected]>
|
||||
and Felipe Morales Moreno <felipe.morales.moreno@gmail.com> */
|
||||
/* FIXME: mappings are not 100% correct? */
|
||||
static struct ir_scancode avermedia_rm_ks[] = {
|
||||
{ 0x0501, KEY_POWER2 },
|
||||
{ 0x0502, KEY_CHANNELUP },
|
||||
{ 0x0503, KEY_CHANNELDOWN },
|
||||
{ 0x0504, KEY_VOLUMEUP },
|
||||
{ 0x0505, KEY_VOLUMEDOWN },
|
||||
{ 0x0506, KEY_MUTE },
|
||||
{ 0x0507, KEY_RIGHT },
|
||||
{ 0x0508, KEY_PROG1 },
|
||||
{ 0x0509, KEY_1 },
|
||||
{ 0x050a, KEY_2 },
|
||||
{ 0x050b, KEY_3 },
|
||||
{ 0x050c, KEY_4 },
|
||||
{ 0x050d, KEY_5 },
|
||||
{ 0x050e, KEY_6 },
|
||||
{ 0x050f, KEY_7 },
|
||||
{ 0x0510, KEY_8 },
|
||||
{ 0x0511, KEY_9 },
|
||||
{ 0x0512, KEY_0 },
|
||||
{ 0x0513, KEY_AUDIO },
|
||||
{ 0x0515, KEY_EPG },
|
||||
{ 0x0516, KEY_PLAY },
|
||||
{ 0x0517, KEY_RECORD },
|
||||
{ 0x0518, KEY_STOP },
|
||||
{ 0x051c, KEY_BACK },
|
||||
{ 0x051d, KEY_FORWARD },
|
||||
{ 0x054d, KEY_LEFT },
|
||||
{ 0x0556, KEY_ZOOM },
|
||||
};
|
||||
|
||||
static struct rc_keymap avermedia_rm_ks_map = {
|
||||
.map = {
|
||||
.scan = avermedia_rm_ks,
|
||||
.size = ARRAY_SIZE(avermedia_rm_ks),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_AVERMEDIA_RM_KS,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_avermedia_rm_ks(void)
|
||||
{
|
||||
return ir_register_map(&avermedia_rm_ks_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_avermedia_rm_ks(void)
|
||||
{
|
||||
ir_unregister_map(&avermedia_rm_ks_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_avermedia_rm_ks)
|
||||
module_exit(exit_rc_map_avermedia_rm_ks)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
102
drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c
Normal file
102
drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* TwinHan AzureWave AD-TU700(704J) remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct ir_scancode azurewave_ad_tu700[] = {
|
||||
{ 0x0000, KEY_TAB }, /* Tab */
|
||||
{ 0x0001, KEY_2 },
|
||||
{ 0x0002, KEY_CHANNELDOWN },
|
||||
{ 0x0003, KEY_1 },
|
||||
{ 0x0004, KEY_MENU }, /* Record List */
|
||||
{ 0x0005, KEY_CHANNELUP },
|
||||
{ 0x0006, KEY_3 },
|
||||
{ 0x0007, KEY_SLEEP }, /* Hibernate */
|
||||
{ 0x0008, KEY_VIDEO }, /* A/V */
|
||||
{ 0x0009, KEY_4 },
|
||||
{ 0x000a, KEY_VOLUMEDOWN },
|
||||
{ 0x000c, KEY_CANCEL }, /* Cancel */
|
||||
{ 0x000d, KEY_7 },
|
||||
{ 0x000e, KEY_AGAIN }, /* Recall */
|
||||
{ 0x000f, KEY_TEXT }, /* Teletext */
|
||||
{ 0x0010, KEY_MUTE },
|
||||
{ 0x0011, KEY_RECORD },
|
||||
{ 0x0012, KEY_FASTFORWARD }, /* FF >> */
|
||||
{ 0x0013, KEY_BACK }, /* Back */
|
||||
{ 0x0014, KEY_PLAY },
|
||||
{ 0x0015, KEY_0 },
|
||||
{ 0x0016, KEY_POWER2 }, /* [red power button] */
|
||||
{ 0x0017, KEY_FAVORITES }, /* Favorite List */
|
||||
{ 0x0018, KEY_RED },
|
||||
{ 0x0019, KEY_8 },
|
||||
{ 0x001a, KEY_STOP },
|
||||
{ 0x001b, KEY_9 },
|
||||
{ 0x001c, KEY_EPG }, /* Info/EPG */
|
||||
{ 0x001d, KEY_5 },
|
||||
{ 0x001e, KEY_VOLUMEUP },
|
||||
{ 0x001f, KEY_6 },
|
||||
{ 0x0040, KEY_REWIND }, /* FR << */
|
||||
{ 0x0041, KEY_PREVIOUS }, /* Replay */
|
||||
{ 0x0042, KEY_NEXT }, /* Skip */
|
||||
{ 0x0043, KEY_SUBTITLE }, /* Subtitle / CC */
|
||||
{ 0x0045, KEY_KPPLUS }, /* Zoom+ */
|
||||
{ 0x0046, KEY_KPMINUS }, /* Zoom- */
|
||||
{ 0x0047, KEY_NEW }, /* PIP */
|
||||
{ 0x0048, KEY_INFO }, /* Preview */
|
||||
{ 0x0049, KEY_MODE }, /* L/R */
|
||||
{ 0x004a, KEY_CLEAR }, /* Clear */
|
||||
{ 0x004b, KEY_UP }, /* up arrow */
|
||||
{ 0x004c, KEY_PAUSE },
|
||||
{ 0x004d, KEY_ZOOM }, /* Full Screen */
|
||||
{ 0x004e, KEY_LEFT }, /* left arrow */
|
||||
{ 0x004f, KEY_OK }, /* Enter / ok */
|
||||
{ 0x0050, KEY_LANGUAGE }, /* SAP */
|
||||
{ 0x0051, KEY_DOWN }, /* down arrow */
|
||||
{ 0x0052, KEY_RIGHT }, /* right arrow */
|
||||
{ 0x0053, KEY_GREEN },
|
||||
{ 0x0054, KEY_CAMERA }, /* Capture */
|
||||
{ 0x005e, KEY_YELLOW },
|
||||
{ 0x005f, KEY_BLUE },
|
||||
};
|
||||
|
||||
static struct rc_keymap azurewave_ad_tu700_map = {
|
||||
.map = {
|
||||
.scan = azurewave_ad_tu700,
|
||||
.size = ARRAY_SIZE(azurewave_ad_tu700),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_AZUREWAVE_AD_TU700,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_azurewave_ad_tu700(void)
|
||||
{
|
||||
return ir_register_map(&azurewave_ad_tu700_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_azurewave_ad_tu700(void)
|
||||
{
|
||||
ir_unregister_map(&azurewave_ad_tu700_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_azurewave_ad_tu700)
|
||||
module_exit(exit_rc_map_azurewave_ad_tu700)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
98
drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c
Normal file
98
drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* DigitalNow TinyTwin remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct ir_scancode digitalnow_tinytwin[] = {
|
||||
{ 0x0000, KEY_MUTE }, /* [symbol speaker] */
|
||||
{ 0x0001, KEY_VOLUMEUP },
|
||||
{ 0x0002, KEY_POWER2 }, /* TV [power button] */
|
||||
{ 0x0003, KEY_2 },
|
||||
{ 0x0004, KEY_3 },
|
||||
{ 0x0005, KEY_4 },
|
||||
{ 0x0006, KEY_6 },
|
||||
{ 0x0007, KEY_7 },
|
||||
{ 0x0008, KEY_8 },
|
||||
{ 0x0009, KEY_NUMERIC_STAR }, /* [*] */
|
||||
{ 0x000a, KEY_0 },
|
||||
{ 0x000b, KEY_NUMERIC_POUND }, /* [#] */
|
||||
{ 0x000c, KEY_RIGHT }, /* [right arrow] */
|
||||
{ 0x000d, KEY_HOMEPAGE }, /* [symbol home] Start */
|
||||
{ 0x000e, KEY_RED }, /* [red] Videos */
|
||||
{ 0x0010, KEY_POWER }, /* PC [power button] */
|
||||
{ 0x0011, KEY_YELLOW }, /* [yellow] Pictures */
|
||||
{ 0x0012, KEY_DOWN }, /* [down arrow] */
|
||||
{ 0x0013, KEY_GREEN }, /* [green] Music */
|
||||
{ 0x0014, KEY_CYCLEWINDOWS }, /* BACK */
|
||||
{ 0x0015, KEY_FAVORITES }, /* MORE */
|
||||
{ 0x0016, KEY_UP }, /* [up arrow] */
|
||||
{ 0x0017, KEY_LEFT }, /* [left arrow] */
|
||||
{ 0x0018, KEY_OK }, /* OK */
|
||||
{ 0x0019, KEY_BLUE }, /* [blue] MyTV */
|
||||
{ 0x001a, KEY_REWIND }, /* REW [<<] */
|
||||
{ 0x001b, KEY_PLAY }, /* PLAY */
|
||||
{ 0x001c, KEY_5 },
|
||||
{ 0x001d, KEY_9 },
|
||||
{ 0x001e, KEY_VOLUMEDOWN },
|
||||
{ 0x001f, KEY_1 },
|
||||
{ 0x0040, KEY_STOP }, /* STOP */
|
||||
{ 0x0042, KEY_PAUSE }, /* PAUSE */
|
||||
{ 0x0043, KEY_SCREEN }, /* Aspect */
|
||||
{ 0x0044, KEY_FORWARD }, /* FWD [>>] */
|
||||
{ 0x0045, KEY_NEXT }, /* SKIP */
|
||||
{ 0x0048, KEY_RECORD }, /* RECORD */
|
||||
{ 0x0049, KEY_VIDEO }, /* RTV */
|
||||
{ 0x004a, KEY_EPG }, /* Guide */
|
||||
{ 0x004b, KEY_CHANNELUP },
|
||||
{ 0x004c, KEY_HELP }, /* Help */
|
||||
{ 0x004d, KEY_RADIO }, /* Radio */
|
||||
{ 0x004f, KEY_CHANNELDOWN },
|
||||
{ 0x0050, KEY_DVD }, /* DVD */
|
||||
{ 0x0051, KEY_AUDIO }, /* Audio */
|
||||
{ 0x0052, KEY_TITLE }, /* Title */
|
||||
{ 0x0053, KEY_NEW }, /* [symbol PIP?] */
|
||||
{ 0x0057, KEY_MENU }, /* Mouse */
|
||||
{ 0x005a, KEY_PREVIOUS }, /* REPLAY */
|
||||
};
|
||||
|
||||
static struct rc_keymap digitalnow_tinytwin_map = {
|
||||
.map = {
|
||||
.scan = digitalnow_tinytwin,
|
||||
.size = ARRAY_SIZE(digitalnow_tinytwin),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_DIGITALNOW_TINYTWIN,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_digitalnow_tinytwin(void)
|
||||
{
|
||||
return ir_register_map(&digitalnow_tinytwin_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_digitalnow_tinytwin(void)
|
||||
{
|
||||
ir_unregister_map(&digitalnow_tinytwin_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_digitalnow_tinytwin)
|
||||
module_exit(exit_rc_map_digitalnow_tinytwin)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
82
drivers/media/IR/keymaps/rc-digittrade.c
Normal file
82
drivers/media/IR/keymaps/rc-digittrade.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Digittrade DVB-T USB Stick remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
/* Digittrade DVB-T USB Stick remote controller. */
|
||||
/* Imported from af9015.h.
|
||||
Initial keytable was from Alain Kalker <miki@dds.nl> */
|
||||
|
||||
/* Digittrade DVB-T USB Stick */
|
||||
static struct ir_scancode digittrade[] = {
|
||||
{ 0x0000, KEY_9 },
|
||||
{ 0x0001, KEY_EPG }, /* EPG */
|
||||
{ 0x0002, KEY_VOLUMEDOWN }, /* Vol Dn */
|
||||
{ 0x0003, KEY_TEXT }, /* TELETEXT */
|
||||
{ 0x0004, KEY_8 },
|
||||
{ 0x0005, KEY_MUTE }, /* MUTE */
|
||||
{ 0x0006, KEY_POWER2 }, /* POWER */
|
||||
{ 0x0009, KEY_ZOOM }, /* FULLSCREEN */
|
||||
{ 0x000a, KEY_RECORD }, /* RECORD */
|
||||
{ 0x000d, KEY_SUBTITLE }, /* SUBTITLE */
|
||||
{ 0x000e, KEY_STOP }, /* STOP */
|
||||
{ 0x0010, KEY_OK }, /* RETURN */
|
||||
{ 0x0011, KEY_2 },
|
||||
{ 0x0012, KEY_4 },
|
||||
{ 0x0015, KEY_3 },
|
||||
{ 0x0016, KEY_5 },
|
||||
{ 0x0017, KEY_CHANNELDOWN }, /* Ch Dn */
|
||||
{ 0x0019, KEY_CHANNELUP }, /* CH Up */
|
||||
{ 0x001a, KEY_PAUSE }, /* PAUSE */
|
||||
{ 0x001b, KEY_1 },
|
||||
{ 0x001d, KEY_AUDIO }, /* DUAL SOUND */
|
||||
{ 0x001e, KEY_PLAY }, /* PLAY */
|
||||
{ 0x001f, KEY_CAMERA }, /* SNAPSHOT */
|
||||
{ 0x0040, KEY_VOLUMEUP }, /* Vol Up */
|
||||
{ 0x0048, KEY_7 },
|
||||
{ 0x004c, KEY_6 },
|
||||
{ 0x004d, KEY_PLAYPAUSE }, /* TIMESHIFT */
|
||||
{ 0x0054, KEY_0 },
|
||||
};
|
||||
|
||||
static struct rc_keymap digittrade_map = {
|
||||
.map = {
|
||||
.scan = digittrade,
|
||||
.size = ARRAY_SIZE(digittrade),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_DIGITTRADE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_digittrade(void)
|
||||
{
|
||||
return ir_register_map(&digittrade_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_digittrade(void)
|
||||
{
|
||||
ir_unregister_map(&digittrade_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_digittrade)
|
||||
module_exit(exit_rc_map_digittrade)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
99
drivers/media/IR/keymaps/rc-leadtek-y04g0051.c
Normal file
99
drivers/media/IR/keymaps/rc-leadtek-y04g0051.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* LeadTek Y04G0051 remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct ir_scancode leadtek_y04g0051[] = {
|
||||
{ 0x0300, KEY_POWER2 },
|
||||
{ 0x0303, KEY_SCREEN },
|
||||
{ 0x0304, KEY_RIGHT },
|
||||
{ 0x0305, KEY_1 },
|
||||
{ 0x0306, KEY_2 },
|
||||
{ 0x0307, KEY_3 },
|
||||
{ 0x0308, KEY_LEFT },
|
||||
{ 0x0309, KEY_4 },
|
||||
{ 0x030a, KEY_5 },
|
||||
{ 0x030b, KEY_6 },
|
||||
{ 0x030c, KEY_UP },
|
||||
{ 0x030d, KEY_7 },
|
||||
{ 0x030e, KEY_8 },
|
||||
{ 0x030f, KEY_9 },
|
||||
{ 0x0310, KEY_DOWN },
|
||||
{ 0x0311, KEY_AGAIN },
|
||||
{ 0x0312, KEY_0 },
|
||||
{ 0x0313, KEY_OK }, /* 1st ok */
|
||||
{ 0x0314, KEY_MUTE },
|
||||
{ 0x0316, KEY_OK }, /* 2nd ok */
|
||||
{ 0x031e, KEY_VIDEO }, /* 2nd video */
|
||||
{ 0x031b, KEY_AUDIO },
|
||||
{ 0x031f, KEY_TEXT },
|
||||
{ 0x0340, KEY_SLEEP },
|
||||
{ 0x0341, KEY_DOT },
|
||||
{ 0x0342, KEY_REWIND },
|
||||
{ 0x0343, KEY_PLAY },
|
||||
{ 0x0344, KEY_FASTFORWARD },
|
||||
{ 0x0345, KEY_TIME },
|
||||
{ 0x0346, KEY_STOP }, /* 2nd stop */
|
||||
{ 0x0347, KEY_RECORD },
|
||||
{ 0x0348, KEY_CAMERA },
|
||||
{ 0x0349, KEY_ESC },
|
||||
{ 0x034a, KEY_NEW },
|
||||
{ 0x034b, KEY_RED },
|
||||
{ 0x034c, KEY_GREEN },
|
||||
{ 0x034d, KEY_YELLOW },
|
||||
{ 0x034e, KEY_BLUE },
|
||||
{ 0x034f, KEY_MENU },
|
||||
{ 0x0350, KEY_STOP }, /* 1st stop */
|
||||
{ 0x0351, KEY_CHANNEL },
|
||||
{ 0x0352, KEY_VIDEO }, /* 1st video */
|
||||
{ 0x0353, KEY_EPG },
|
||||
{ 0x0354, KEY_PREVIOUS },
|
||||
{ 0x0355, KEY_NEXT },
|
||||
{ 0x0356, KEY_TV },
|
||||
{ 0x035a, KEY_VOLUMEDOWN },
|
||||
{ 0x035b, KEY_CHANNELUP },
|
||||
{ 0x035e, KEY_VOLUMEUP },
|
||||
{ 0x035f, KEY_CHANNELDOWN },
|
||||
};
|
||||
|
||||
static struct rc_keymap leadtek_y04g0051_map = {
|
||||
.map = {
|
||||
.scan = leadtek_y04g0051,
|
||||
.size = ARRAY_SIZE(leadtek_y04g0051),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_LEADTEK_Y04G0051,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_leadtek_y04g0051(void)
|
||||
{
|
||||
return ir_register_map(&leadtek_y04g0051_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_leadtek_y04g0051(void)
|
||||
{
|
||||
ir_unregister_map(&leadtek_y04g0051_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_leadtek_y04g0051)
|
||||
module_exit(exit_rc_map_leadtek_y04g0051)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
68
drivers/media/IR/keymaps/rc-lme2510.c
Normal file
68
drivers/media/IR/keymaps/rc-lme2510.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/* LME2510 remote control
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
|
||||
static struct ir_scancode lme2510_rc[] = {
|
||||
{ 0xba45, KEY_0 },
|
||||
{ 0xa05f, KEY_1 },
|
||||
{ 0xaf50, KEY_2 },
|
||||
{ 0xa25d, KEY_3 },
|
||||
{ 0xbe41, KEY_4 },
|
||||
{ 0xf50a, KEY_5 },
|
||||
{ 0xbd42, KEY_6 },
|
||||
{ 0xb847, KEY_7 },
|
||||
{ 0xb649, KEY_8 },
|
||||
{ 0xfa05, KEY_9 },
|
||||
{ 0xbc43, KEY_POWER },
|
||||
{ 0xb946, KEY_SUBTITLE },
|
||||
{ 0xf906, KEY_PAUSE },
|
||||
{ 0xfc03, KEY_MEDIA_REPEAT},
|
||||
{ 0xfd02, KEY_PAUSE },
|
||||
{ 0xa15e, KEY_VOLUMEUP },
|
||||
{ 0xa35c, KEY_VOLUMEDOWN },
|
||||
{ 0xf609, KEY_CHANNELUP },
|
||||
{ 0xe51a, KEY_CHANNELDOWN },
|
||||
{ 0xe11e, KEY_PLAY },
|
||||
{ 0xe41b, KEY_ZOOM },
|
||||
{ 0xa659, KEY_MUTE },
|
||||
{ 0xa55a, KEY_TV },
|
||||
{ 0xe718, KEY_RECORD },
|
||||
{ 0xf807, KEY_EPG },
|
||||
{ 0xfe01, KEY_STOP },
|
||||
|
||||
};
|
||||
|
||||
static struct rc_keymap lme2510_map = {
|
||||
.map = {
|
||||
.scan = lme2510_rc,
|
||||
.size = ARRAY_SIZE(lme2510_rc),
|
||||
.ir_type = IR_TYPE_UNKNOWN,
|
||||
.name = RC_MAP_LME2510,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_lme2510_map(void)
|
||||
{
|
||||
return ir_register_map(&lme2510_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_lme2510_map(void)
|
||||
{
|
||||
ir_unregister_map(&lme2510_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_lme2510_map)
|
||||
module_exit(exit_rc_lme2510_map)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Malcolm Priestley [email protected]");
|
||||
67
drivers/media/IR/keymaps/rc-msi-digivox-ii.c
Normal file
67
drivers/media/IR/keymaps/rc-msi-digivox-ii.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* MSI DIGIVOX mini II remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct ir_scancode msi_digivox_ii[] = {
|
||||
{ 0x0002, KEY_2 },
|
||||
{ 0x0003, KEY_UP }, /* up */
|
||||
{ 0x0004, KEY_3 },
|
||||
{ 0x0005, KEY_CHANNELDOWN },
|
||||
{ 0x0008, KEY_5 },
|
||||
{ 0x0009, KEY_0 },
|
||||
{ 0x000b, KEY_8 },
|
||||
{ 0x000d, KEY_DOWN }, /* down */
|
||||
{ 0x0010, KEY_9 },
|
||||
{ 0x0011, KEY_7 },
|
||||
{ 0x0014, KEY_VOLUMEUP },
|
||||
{ 0x0015, KEY_CHANNELUP },
|
||||
{ 0x0016, KEY_OK },
|
||||
{ 0x0017, KEY_POWER2 },
|
||||
{ 0x001a, KEY_1 },
|
||||
{ 0x001c, KEY_4 },
|
||||
{ 0x001d, KEY_6 },
|
||||
{ 0x001f, KEY_VOLUMEDOWN },
|
||||
};
|
||||
|
||||
static struct rc_keymap msi_digivox_ii_map = {
|
||||
.map = {
|
||||
.scan = msi_digivox_ii,
|
||||
.size = ARRAY_SIZE(msi_digivox_ii),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_MSI_DIGIVOX_II,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_msi_digivox_ii(void)
|
||||
{
|
||||
return ir_register_map(&msi_digivox_ii_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_msi_digivox_ii(void)
|
||||
{
|
||||
ir_unregister_map(&msi_digivox_ii_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_msi_digivox_ii)
|
||||
module_exit(exit_rc_map_msi_digivox_ii)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
85
drivers/media/IR/keymaps/rc-msi-digivox-iii.c
Normal file
85
drivers/media/IR/keymaps/rc-msi-digivox-iii.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* MSI DIGIVOX mini III remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
/* MSI DIGIVOX mini III */
|
||||
/* Uses NEC extended 0x61d6. */
|
||||
/* This remote seems to be same as rc-kworld-315u.c. Anyhow, add new remote
|
||||
since rc-kworld-315u.c lacks NEC extended address byte. */
|
||||
static struct ir_scancode msi_digivox_iii[] = {
|
||||
{ 0x61d601, KEY_VIDEO }, /* Source */
|
||||
{ 0x61d602, KEY_3 },
|
||||
{ 0x61d603, KEY_POWER }, /* ShutDown */
|
||||
{ 0x61d604, KEY_1 },
|
||||
{ 0x61d605, KEY_5 },
|
||||
{ 0x61d606, KEY_6 },
|
||||
{ 0x61d607, KEY_CHANNELDOWN }, /* CH- */
|
||||
{ 0x61d608, KEY_2 },
|
||||
{ 0x61d609, KEY_CHANNELUP }, /* CH+ */
|
||||
{ 0x61d60a, KEY_9 },
|
||||
{ 0x61d60b, KEY_ZOOM }, /* Zoom */
|
||||
{ 0x61d60c, KEY_7 },
|
||||
{ 0x61d60d, KEY_8 },
|
||||
{ 0x61d60e, KEY_VOLUMEUP }, /* Vol+ */
|
||||
{ 0x61d60f, KEY_4 },
|
||||
{ 0x61d610, KEY_ESC }, /* [back up arrow] */
|
||||
{ 0x61d611, KEY_0 },
|
||||
{ 0x61d612, KEY_OK }, /* [enter arrow] */
|
||||
{ 0x61d613, KEY_VOLUMEDOWN }, /* Vol- */
|
||||
{ 0x61d614, KEY_RECORD }, /* Rec */
|
||||
{ 0x61d615, KEY_STOP }, /* Stop */
|
||||
{ 0x61d616, KEY_PLAY }, /* Play */
|
||||
{ 0x61d617, KEY_MUTE }, /* Mute */
|
||||
{ 0x61d618, KEY_UP },
|
||||
{ 0x61d619, KEY_DOWN },
|
||||
{ 0x61d61a, KEY_LEFT },
|
||||
{ 0x61d61b, KEY_RIGHT },
|
||||
{ 0x61d61c, KEY_RED },
|
||||
{ 0x61d61d, KEY_GREEN },
|
||||
{ 0x61d61e, KEY_YELLOW },
|
||||
{ 0x61d61f, KEY_BLUE },
|
||||
{ 0x61d643, KEY_POWER2 }, /* [red power button] */
|
||||
};
|
||||
|
||||
static struct rc_keymap msi_digivox_iii_map = {
|
||||
.map = {
|
||||
.scan = msi_digivox_iii,
|
||||
.size = ARRAY_SIZE(msi_digivox_iii),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_MSI_DIGIVOX_III,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_msi_digivox_iii(void)
|
||||
{
|
||||
return ir_register_map(&msi_digivox_iii_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_msi_digivox_iii(void)
|
||||
{
|
||||
ir_unregister_map(&msi_digivox_iii_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_msi_digivox_iii)
|
||||
module_exit(exit_rc_map_msi_digivox_iii)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/* rc-rc5-streamzap.c - Keytable for Streamzap PC Remote, for use
|
||||
* with the Streamzap PC Remote IR Receiver.
|
||||
*
|
||||
* Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct ir_scancode rc5_streamzap[] = {
|
||||
/*
|
||||
* FIXME: The Streamzap remote isn't actually true RC-5, it has an extra
|
||||
* bit in it, which presently throws the in-kernel RC-5 decoder for a loop.
|
||||
* We either have to enhance the decoder to support it, add a new decoder,
|
||||
* or just rely on lirc userspace decoding.
|
||||
*/
|
||||
{ 0x00, KEY_NUMERIC_0 },
|
||||
{ 0x01, KEY_NUMERIC_1 },
|
||||
{ 0x02, KEY_NUMERIC_2 },
|
||||
{ 0x03, KEY_NUMERIC_3 },
|
||||
{ 0x04, KEY_NUMERIC_4 },
|
||||
{ 0x05, KEY_NUMERIC_5 },
|
||||
{ 0x06, KEY_NUMERIC_6 },
|
||||
{ 0x07, KEY_NUMERIC_7 },
|
||||
{ 0x08, KEY_NUMERIC_8 },
|
||||
{ 0x0a, KEY_POWER },
|
||||
{ 0x0b, KEY_MUTE },
|
||||
{ 0x0c, KEY_CHANNELUP },
|
||||
{ 0x0d, KEY_VOLUMEUP },
|
||||
{ 0x0e, KEY_CHANNELDOWN },
|
||||
{ 0x0f, KEY_VOLUMEDOWN },
|
||||
{ 0x10, KEY_UP },
|
||||
{ 0x11, KEY_LEFT },
|
||||
{ 0x12, KEY_OK },
|
||||
{ 0x13, KEY_RIGHT },
|
||||
{ 0x14, KEY_DOWN },
|
||||
{ 0x15, KEY_MENU },
|
||||
{ 0x16, KEY_EXIT },
|
||||
{ 0x17, KEY_PLAY },
|
||||
{ 0x18, KEY_PAUSE },
|
||||
{ 0x19, KEY_STOP },
|
||||
{ 0x1a, KEY_BACK },
|
||||
{ 0x1b, KEY_FORWARD },
|
||||
{ 0x1c, KEY_RECORD },
|
||||
{ 0x1d, KEY_REWIND },
|
||||
{ 0x1e, KEY_FASTFORWARD },
|
||||
{ 0x20, KEY_RED },
|
||||
{ 0x21, KEY_GREEN },
|
||||
{ 0x22, KEY_YELLOW },
|
||||
{ 0x23, KEY_BLUE },
|
||||
|
||||
};
|
||||
|
||||
static struct rc_keymap rc5_streamzap_map = {
|
||||
.map = {
|
||||
.scan = rc5_streamzap,
|
||||
.size = ARRAY_SIZE(rc5_streamzap),
|
||||
.ir_type = IR_TYPE_RC5,
|
||||
.name = RC_MAP_RC5_STREAMZAP,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_rc5_streamzap(void)
|
||||
{
|
||||
return ir_register_map(&rc5_streamzap_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_rc5_streamzap(void)
|
||||
{
|
||||
ir_unregister_map(&rc5_streamzap_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_rc5_streamzap)
|
||||
module_exit(exit_rc_map_rc5_streamzap)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jarod Wilson <[email protected]>");
|
||||
|
|
@ -12,35 +12,8 @@
|
|||
#include <media/rc-map.h>
|
||||
|
||||
static struct ir_scancode rc6_mce[] = {
|
||||
{ 0x800f0415, KEY_REWIND },
|
||||
{ 0x800f0414, KEY_FASTFORWARD },
|
||||
{ 0x800f041b, KEY_PREVIOUS },
|
||||
{ 0x800f041a, KEY_NEXT },
|
||||
|
||||
{ 0x800f0416, KEY_PLAY },
|
||||
{ 0x800f0418, KEY_PAUSE },
|
||||
{ 0x800f046e, KEY_PLAYPAUSE },
|
||||
{ 0x800f0419, KEY_STOP },
|
||||
{ 0x800f0417, KEY_RECORD },
|
||||
|
||||
{ 0x800f041e, KEY_UP },
|
||||
{ 0x800f041f, KEY_DOWN },
|
||||
{ 0x800f0420, KEY_LEFT },
|
||||
{ 0x800f0421, KEY_RIGHT },
|
||||
|
||||
{ 0x800f040b, KEY_ENTER },
|
||||
{ 0x800f0422, KEY_OK },
|
||||
{ 0x800f0423, KEY_EXIT },
|
||||
{ 0x800f040a, KEY_DELETE },
|
||||
|
||||
{ 0x800f040e, KEY_MUTE },
|
||||
{ 0x800f0410, KEY_VOLUMEUP },
|
||||
{ 0x800f0411, KEY_VOLUMEDOWN },
|
||||
{ 0x800f0412, KEY_CHANNELUP },
|
||||
{ 0x800f0413, KEY_CHANNELDOWN },
|
||||
{ 0x800f043a, KEY_BRIGHTNESSUP },
|
||||
{ 0x800f0480, KEY_BRIGHTNESSDOWN },
|
||||
|
||||
{ 0x800f0400, KEY_NUMERIC_0 },
|
||||
{ 0x800f0401, KEY_NUMERIC_1 },
|
||||
{ 0x800f0402, KEY_NUMERIC_2 },
|
||||
{ 0x800f0403, KEY_NUMERIC_3 },
|
||||
|
|
@ -50,38 +23,67 @@ static struct ir_scancode rc6_mce[] = {
|
|||
{ 0x800f0407, KEY_NUMERIC_7 },
|
||||
{ 0x800f0408, KEY_NUMERIC_8 },
|
||||
{ 0x800f0409, KEY_NUMERIC_9 },
|
||||
{ 0x800f0400, KEY_NUMERIC_0 },
|
||||
|
||||
{ 0x800f041d, KEY_NUMERIC_STAR },
|
||||
{ 0x800f040a, KEY_DELETE },
|
||||
{ 0x800f040b, KEY_ENTER },
|
||||
{ 0x800f040c, KEY_POWER },
|
||||
{ 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
|
||||
{ 0x800f040e, KEY_MUTE },
|
||||
{ 0x800f040f, KEY_INFO },
|
||||
|
||||
{ 0x800f0410, KEY_VOLUMEUP },
|
||||
{ 0x800f0411, KEY_VOLUMEDOWN },
|
||||
{ 0x800f0412, KEY_CHANNELUP },
|
||||
{ 0x800f0413, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x800f0414, KEY_FASTFORWARD },
|
||||
{ 0x800f0415, KEY_REWIND },
|
||||
{ 0x800f0416, KEY_PLAY },
|
||||
{ 0x800f0417, KEY_RECORD },
|
||||
{ 0x800f0418, KEY_PAUSE },
|
||||
{ 0x800f046e, KEY_PLAYPAUSE },
|
||||
{ 0x800f0419, KEY_STOP },
|
||||
{ 0x800f041a, KEY_NEXT },
|
||||
{ 0x800f041b, KEY_PREVIOUS },
|
||||
{ 0x800f041c, KEY_NUMERIC_POUND },
|
||||
{ 0x800f041d, KEY_NUMERIC_STAR },
|
||||
|
||||
{ 0x800f041e, KEY_UP },
|
||||
{ 0x800f041f, KEY_DOWN },
|
||||
{ 0x800f0420, KEY_LEFT },
|
||||
{ 0x800f0421, KEY_RIGHT },
|
||||
|
||||
{ 0x800f0422, KEY_OK },
|
||||
{ 0x800f0423, KEY_EXIT },
|
||||
{ 0x800f0424, KEY_DVD },
|
||||
{ 0x800f0425, KEY_TUNER }, /* LiveTV */
|
||||
{ 0x800f0426, KEY_EPG }, /* Guide */
|
||||
{ 0x800f0427, KEY_ZOOM }, /* Aspect */
|
||||
|
||||
{ 0x800f043a, KEY_BRIGHTNESSUP },
|
||||
|
||||
{ 0x800f0446, KEY_TV },
|
||||
{ 0x800f0447, KEY_AUDIO }, /* My Music */
|
||||
{ 0x800f0448, KEY_PVR }, /* RecordedTV */
|
||||
{ 0x800f0447, KEY_AUDIO }, /* My Music */
|
||||
{ 0x800f0448, KEY_PVR }, /* RecordedTV */
|
||||
{ 0x800f0449, KEY_CAMERA },
|
||||
{ 0x800f044a, KEY_VIDEO },
|
||||
{ 0x800f0424, KEY_DVD },
|
||||
{ 0x800f0425, KEY_TUNER }, /* LiveTV */
|
||||
{ 0x800f044c, KEY_LANGUAGE },
|
||||
{ 0x800f044d, KEY_TITLE },
|
||||
{ 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
|
||||
|
||||
{ 0x800f0450, KEY_RADIO },
|
||||
|
||||
{ 0x800f044c, KEY_LANGUAGE },
|
||||
{ 0x800f0427, KEY_ZOOM }, /* Aspect */
|
||||
|
||||
{ 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
|
||||
{ 0x800f045b, KEY_RED },
|
||||
{ 0x800f045c, KEY_GREEN },
|
||||
{ 0x800f045d, KEY_YELLOW },
|
||||
{ 0x800f045e, KEY_BLUE },
|
||||
|
||||
{ 0x800f040f, KEY_INFO },
|
||||
{ 0x800f0426, KEY_EPG }, /* Guide */
|
||||
{ 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
|
||||
{ 0x800f044d, KEY_TITLE },
|
||||
|
||||
{ 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
|
||||
|
||||
{ 0x800f040c, KEY_POWER },
|
||||
{ 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
|
||||
{ 0x800f046e, KEY_PLAYPAUSE },
|
||||
{ 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
|
||||
|
||||
{ 0x800f0480, KEY_BRIGHTNESSDOWN },
|
||||
{ 0x800f0481, KEY_PLAYPAUSE },
|
||||
};
|
||||
|
||||
static struct rc_keymap rc6_mce_map = {
|
||||
|
|
|
|||
82
drivers/media/IR/keymaps/rc-streamzap.c
Normal file
82
drivers/media/IR/keymaps/rc-streamzap.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/* rc-streamzap.c - Keytable for Streamzap PC Remote, for use
|
||||
* with the Streamzap PC Remote IR Receiver.
|
||||
*
|
||||
* Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct ir_scancode streamzap[] = {
|
||||
/*
|
||||
* The Streamzap remote is almost, but not quite, RC-5, as it has an extra
|
||||
* bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently,
|
||||
* an additional RC-5-sz decoder is being deployed to support it, but it
|
||||
* may be possible to merge it back with the standard RC-5 decoder.
|
||||
*/
|
||||
{ 0x28c0, KEY_NUMERIC_0 },
|
||||
{ 0x28c1, KEY_NUMERIC_1 },
|
||||
{ 0x28c2, KEY_NUMERIC_2 },
|
||||
{ 0x28c3, KEY_NUMERIC_3 },
|
||||
{ 0x28c4, KEY_NUMERIC_4 },
|
||||
{ 0x28c5, KEY_NUMERIC_5 },
|
||||
{ 0x28c6, KEY_NUMERIC_6 },
|
||||
{ 0x28c7, KEY_NUMERIC_7 },
|
||||
{ 0x28c8, KEY_NUMERIC_8 },
|
||||
{ 0x28c9, KEY_NUMERIC_9 },
|
||||
{ 0x28ca, KEY_POWER },
|
||||
{ 0x28cb, KEY_MUTE },
|
||||
{ 0x28cc, KEY_CHANNELUP },
|
||||
{ 0x28cd, KEY_VOLUMEUP },
|
||||
{ 0x28ce, KEY_CHANNELDOWN },
|
||||
{ 0x28cf, KEY_VOLUMEDOWN },
|
||||
{ 0x28d0, KEY_UP },
|
||||
{ 0x28d1, KEY_LEFT },
|
||||
{ 0x28d2, KEY_OK },
|
||||
{ 0x28d3, KEY_RIGHT },
|
||||
{ 0x28d4, KEY_DOWN },
|
||||
{ 0x28d5, KEY_MENU },
|
||||
{ 0x28d6, KEY_EXIT },
|
||||
{ 0x28d7, KEY_PLAY },
|
||||
{ 0x28d8, KEY_PAUSE },
|
||||
{ 0x28d9, KEY_STOP },
|
||||
{ 0x28da, KEY_BACK },
|
||||
{ 0x28db, KEY_FORWARD },
|
||||
{ 0x28dc, KEY_RECORD },
|
||||
{ 0x28dd, KEY_REWIND },
|
||||
{ 0x28de, KEY_FASTFORWARD },
|
||||
{ 0x28e0, KEY_RED },
|
||||
{ 0x28e1, KEY_GREEN },
|
||||
{ 0x28e2, KEY_YELLOW },
|
||||
{ 0x28e3, KEY_BLUE },
|
||||
|
||||
};
|
||||
|
||||
static struct rc_keymap streamzap_map = {
|
||||
.map = {
|
||||
.scan = streamzap,
|
||||
.size = ARRAY_SIZE(streamzap),
|
||||
.ir_type = IR_TYPE_RC5_SZ,
|
||||
.name = RC_MAP_STREAMZAP,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_streamzap(void)
|
||||
{
|
||||
return ir_register_map(&streamzap_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_streamzap(void)
|
||||
{
|
||||
ir_unregister_map(&streamzap_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_streamzap)
|
||||
module_exit(exit_rc_map_streamzap)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jarod Wilson <[email protected]>");
|
||||
79
drivers/media/IR/keymaps/rc-terratec-slim.c
Normal file
79
drivers/media/IR/keymaps/rc-terratec-slim.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* TerraTec remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
/* TerraTec slim remote, 7 rows, 4 columns. */
|
||||
/* Uses NEC extended 0x02bd. */
|
||||
static struct ir_scancode terratec_slim[] = {
|
||||
{ 0x02bd00, KEY_1 },
|
||||
{ 0x02bd01, KEY_2 },
|
||||
{ 0x02bd02, KEY_3 },
|
||||
{ 0x02bd03, KEY_4 },
|
||||
{ 0x02bd04, KEY_5 },
|
||||
{ 0x02bd05, KEY_6 },
|
||||
{ 0x02bd06, KEY_7 },
|
||||
{ 0x02bd07, KEY_8 },
|
||||
{ 0x02bd08, KEY_9 },
|
||||
{ 0x02bd09, KEY_0 },
|
||||
{ 0x02bd0a, KEY_MUTE },
|
||||
{ 0x02bd0b, KEY_NEW }, /* symbol: PIP */
|
||||
{ 0x02bd0e, KEY_VOLUMEDOWN },
|
||||
{ 0x02bd0f, KEY_PLAYPAUSE },
|
||||
{ 0x02bd10, KEY_RIGHT },
|
||||
{ 0x02bd11, KEY_LEFT },
|
||||
{ 0x02bd12, KEY_UP },
|
||||
{ 0x02bd13, KEY_DOWN },
|
||||
{ 0x02bd15, KEY_OK },
|
||||
{ 0x02bd16, KEY_STOP },
|
||||
{ 0x02bd17, KEY_CAMERA }, /* snapshot */
|
||||
{ 0x02bd18, KEY_CHANNELUP },
|
||||
{ 0x02bd19, KEY_RECORD },
|
||||
{ 0x02bd1a, KEY_CHANNELDOWN },
|
||||
{ 0x02bd1c, KEY_ESC },
|
||||
{ 0x02bd1f, KEY_VOLUMEUP },
|
||||
{ 0x02bd44, KEY_EPG },
|
||||
{ 0x02bd45, KEY_POWER2 }, /* [red power button] */
|
||||
};
|
||||
|
||||
static struct rc_keymap terratec_slim_map = {
|
||||
.map = {
|
||||
.scan = terratec_slim,
|
||||
.size = ARRAY_SIZE(terratec_slim),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_TERRATEC_SLIM,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_terratec_slim(void)
|
||||
{
|
||||
return ir_register_map(&terratec_slim_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_terratec_slim(void)
|
||||
{
|
||||
ir_unregister_map(&terratec_slim_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_terratec_slim)
|
||||
module_exit(exit_rc_map_terratec_slim)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
85
drivers/media/IR/keymaps/rc-total-media-in-hand.c
Normal file
85
drivers/media/IR/keymaps/rc-total-media-in-hand.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Total Media In Hand remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
/* Uses NEC extended 0x02bd */
|
||||
static struct ir_scancode total_media_in_hand[] = {
|
||||
{ 0x02bd00, KEY_1 },
|
||||
{ 0x02bd01, KEY_2 },
|
||||
{ 0x02bd02, KEY_3 },
|
||||
{ 0x02bd03, KEY_4 },
|
||||
{ 0x02bd04, KEY_5 },
|
||||
{ 0x02bd05, KEY_6 },
|
||||
{ 0x02bd06, KEY_7 },
|
||||
{ 0x02bd07, KEY_8 },
|
||||
{ 0x02bd08, KEY_9 },
|
||||
{ 0x02bd09, KEY_0 },
|
||||
{ 0x02bd0a, KEY_MUTE },
|
||||
{ 0x02bd0b, KEY_CYCLEWINDOWS }, /* yellow, [min / max] */
|
||||
{ 0x02bd0c, KEY_VIDEO }, /* TV / AV */
|
||||
{ 0x02bd0e, KEY_VOLUMEDOWN },
|
||||
{ 0x02bd0f, KEY_TIME }, /* TimeShift */
|
||||
{ 0x02bd10, KEY_RIGHT }, /* right arrow */
|
||||
{ 0x02bd11, KEY_LEFT }, /* left arrow */
|
||||
{ 0x02bd12, KEY_UP }, /* up arrow */
|
||||
{ 0x02bd13, KEY_DOWN }, /* down arrow */
|
||||
{ 0x02bd14, KEY_POWER2 }, /* [red] */
|
||||
{ 0x02bd15, KEY_OK }, /* OK */
|
||||
{ 0x02bd16, KEY_STOP },
|
||||
{ 0x02bd17, KEY_CAMERA }, /* Snapshot */
|
||||
{ 0x02bd18, KEY_CHANNELUP },
|
||||
{ 0x02bd19, KEY_RECORD },
|
||||
{ 0x02bd1a, KEY_CHANNELDOWN },
|
||||
{ 0x02bd1c, KEY_ESC }, /* Esc */
|
||||
{ 0x02bd1e, KEY_PLAY },
|
||||
{ 0x02bd1f, KEY_VOLUMEUP },
|
||||
{ 0x02bd40, KEY_PAUSE },
|
||||
{ 0x02bd41, KEY_FASTFORWARD }, /* FF >> */
|
||||
{ 0x02bd42, KEY_REWIND }, /* FR << */
|
||||
{ 0x02bd43, KEY_ZOOM }, /* [window + mouse pointer] */
|
||||
{ 0x02bd44, KEY_SHUFFLE }, /* Shuffle */
|
||||
{ 0x02bd45, KEY_INFO }, /* [red (I)] */
|
||||
};
|
||||
|
||||
static struct rc_keymap total_media_in_hand_map = {
|
||||
.map = {
|
||||
.scan = total_media_in_hand,
|
||||
.size = ARRAY_SIZE(total_media_in_hand),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_TOTAL_MEDIA_IN_HAND,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_total_media_in_hand(void)
|
||||
{
|
||||
return ir_register_map(&total_media_in_hand_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_total_media_in_hand(void)
|
||||
{
|
||||
ir_unregister_map(&total_media_in_hand_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_total_media_in_hand)
|
||||
module_exit(exit_rc_map_total_media_in_hand)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
80
drivers/media/IR/keymaps/rc-trekstor.c
Normal file
80
drivers/media/IR/keymaps/rc-trekstor.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* TrekStor remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
|
||||
/* TrekStor DVB-T USB Stick remote controller. */
|
||||
/* Imported from af9015.h.
|
||||
Initial keytable was from Marc Schneider <macke@macke.org> */
|
||||
static struct ir_scancode trekstor[] = {
|
||||
{ 0x0084, KEY_0 },
|
||||
{ 0x0085, KEY_MUTE }, /* Mute */
|
||||
{ 0x0086, KEY_HOMEPAGE }, /* Home */
|
||||
{ 0x0087, KEY_UP }, /* Up */
|
||||
{ 0x0088, KEY_OK }, /* OK */
|
||||
{ 0x0089, KEY_RIGHT }, /* Right */
|
||||
{ 0x008a, KEY_FASTFORWARD }, /* Fast forward */
|
||||
{ 0x008b, KEY_VOLUMEUP }, /* Volume + */
|
||||
{ 0x008c, KEY_DOWN }, /* Down */
|
||||
{ 0x008d, KEY_PLAY }, /* Play/Pause */
|
||||
{ 0x008e, KEY_STOP }, /* Stop */
|
||||
{ 0x008f, KEY_EPG }, /* Info/EPG */
|
||||
{ 0x0090, KEY_7 },
|
||||
{ 0x0091, KEY_4 },
|
||||
{ 0x0092, KEY_1 },
|
||||
{ 0x0093, KEY_CHANNELDOWN }, /* Channel - */
|
||||
{ 0x0094, KEY_8 },
|
||||
{ 0x0095, KEY_5 },
|
||||
{ 0x0096, KEY_2 },
|
||||
{ 0x0097, KEY_CHANNELUP }, /* Channel + */
|
||||
{ 0x0098, KEY_9 },
|
||||
{ 0x0099, KEY_6 },
|
||||
{ 0x009a, KEY_3 },
|
||||
{ 0x009b, KEY_VOLUMEDOWN }, /* Volume - */
|
||||
{ 0x009c, KEY_TV }, /* TV */
|
||||
{ 0x009d, KEY_RECORD }, /* Record */
|
||||
{ 0x009e, KEY_REWIND }, /* Rewind */
|
||||
{ 0x009f, KEY_LEFT }, /* Left */
|
||||
};
|
||||
|
||||
static struct rc_keymap trekstor_map = {
|
||||
.map = {
|
||||
.scan = trekstor,
|
||||
.size = ARRAY_SIZE(trekstor),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
.name = RC_MAP_TREKSTOR,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_trekstor(void)
|
||||
{
|
||||
return ir_register_map(&trekstor_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_trekstor(void)
|
||||
{
|
||||
ir_unregister_map(&trekstor_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_trekstor)
|
||||
module_exit(exit_rc_map_trekstor)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
87
drivers/media/IR/keymaps/rc-twinhan1027.c
Normal file
87
drivers/media/IR/keymaps/rc-twinhan1027.c
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#include <media/rc-map.h>
|
||||
|
||||
static struct ir_scancode twinhan_vp1027[] = {
|
||||
{ 0x16, KEY_POWER2 },
|
||||
{ 0x17, KEY_FAVORITES },
|
||||
{ 0x0f, KEY_TEXT },
|
||||
{ 0x48, KEY_INFO},
|
||||
{ 0x1c, KEY_EPG },
|
||||
{ 0x04, KEY_LIST },
|
||||
|
||||
{ 0x03, KEY_1 },
|
||||
{ 0x01, KEY_2 },
|
||||
{ 0x06, KEY_3 },
|
||||
{ 0x09, KEY_4 },
|
||||
{ 0x1d, KEY_5 },
|
||||
{ 0x1f, KEY_6 },
|
||||
{ 0x0d, KEY_7 },
|
||||
{ 0x19, KEY_8 },
|
||||
{ 0x1b, KEY_9 },
|
||||
{ 0x15, KEY_0 },
|
||||
|
||||
{ 0x0c, KEY_CANCEL },
|
||||
{ 0x4a, KEY_CLEAR },
|
||||
{ 0x13, KEY_BACKSPACE },
|
||||
{ 0x00, KEY_TAB },
|
||||
|
||||
{ 0x4b, KEY_UP },
|
||||
{ 0x51, KEY_DOWN },
|
||||
{ 0x4e, KEY_LEFT },
|
||||
{ 0x52, KEY_RIGHT },
|
||||
{ 0x4f, KEY_ENTER },
|
||||
|
||||
{ 0x1e, KEY_VOLUMEUP },
|
||||
{ 0x0a, KEY_VOLUMEDOWN },
|
||||
{ 0x02, KEY_CHANNELDOWN },
|
||||
{ 0x05, KEY_CHANNELUP },
|
||||
{ 0x11, KEY_RECORD },
|
||||
|
||||
{ 0x14, KEY_PLAY },
|
||||
{ 0x4c, KEY_PAUSE },
|
||||
{ 0x1a, KEY_STOP },
|
||||
{ 0x40, KEY_REWIND },
|
||||
{ 0x12, KEY_FASTFORWARD },
|
||||
{ 0x41, KEY_PREVIOUSSONG },
|
||||
{ 0x42, KEY_NEXTSONG },
|
||||
{ 0x54, KEY_SAVE },
|
||||
{ 0x50, KEY_LANGUAGE },
|
||||
{ 0x47, KEY_MEDIA },
|
||||
{ 0x4d, KEY_SCREEN },
|
||||
{ 0x43, KEY_SUBTITLE },
|
||||
{ 0x10, KEY_MUTE },
|
||||
{ 0x49, KEY_AUDIO },
|
||||
{ 0x07, KEY_SLEEP },
|
||||
{ 0x08, KEY_VIDEO },
|
||||
{ 0x0e, KEY_AGAIN },
|
||||
{ 0x45, KEY_EQUAL },
|
||||
{ 0x46, KEY_MINUS },
|
||||
{ 0x18, KEY_RED },
|
||||
{ 0x53, KEY_GREEN },
|
||||
{ 0x5e, KEY_YELLOW },
|
||||
{ 0x5f, KEY_BLUE },
|
||||
};
|
||||
|
||||
static struct rc_keymap twinhan_vp1027_map = {
|
||||
.map = {
|
||||
.scan = twinhan_vp1027,
|
||||
.size = ARRAY_SIZE(twinhan_vp1027),
|
||||
.ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_TWINHAN_VP1027_DVBS,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_twinhan_vp1027(void)
|
||||
{
|
||||
return ir_register_map(&twinhan_vp1027_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_twinhan_vp1027(void)
|
||||
{
|
||||
ir_unregister_map(&twinhan_vp1027_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_twinhan_vp1027)
|
||||
module_exit(exit_rc_map_twinhan_vp1027)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Sergey Ivanov <[email protected]>");
|
||||
|
|
@ -57,13 +57,12 @@ struct irctl {
|
|||
|
||||
struct task_struct *task;
|
||||
long jiffies_to_wait;
|
||||
|
||||
struct cdev cdev;
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(lirc_dev_lock);
|
||||
|
||||
static struct irctl *irctls[MAX_IRCTL_DEVICES];
|
||||
static struct cdev cdevs[MAX_IRCTL_DEVICES];
|
||||
|
||||
/* Only used for sysfs but defined to void otherwise */
|
||||
static struct class *lirc_class;
|
||||
|
|
@ -71,15 +70,13 @@ static struct class *lirc_class;
|
|||
/* helper function
|
||||
* initializes the irctl structure
|
||||
*/
|
||||
static void init_irctl(struct irctl *ir)
|
||||
static void lirc_irctl_init(struct irctl *ir)
|
||||
{
|
||||
dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n",
|
||||
ir->d.name, ir->d.minor);
|
||||
mutex_init(&ir->irctl_lock);
|
||||
ir->d.minor = NOPLUG;
|
||||
}
|
||||
|
||||
static void cleanup(struct irctl *ir)
|
||||
static void lirc_irctl_cleanup(struct irctl *ir)
|
||||
{
|
||||
dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor);
|
||||
|
||||
|
|
@ -96,7 +93,7 @@ static void cleanup(struct irctl *ir)
|
|||
* reads key codes from driver and puts them into buffer
|
||||
* returns 0 on success
|
||||
*/
|
||||
static int add_to_buf(struct irctl *ir)
|
||||
static int lirc_add_to_buf(struct irctl *ir)
|
||||
{
|
||||
if (ir->d.add_to_buf) {
|
||||
int res = -ENODATA;
|
||||
|
|
@ -139,7 +136,7 @@ static int lirc_thread(void *irctl)
|
|||
}
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
if (!add_to_buf(ir))
|
||||
if (!lirc_add_to_buf(ir))
|
||||
wake_up_interruptible(&ir->buf->wait_poll);
|
||||
} else {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
|
@ -154,12 +151,15 @@ static int lirc_thread(void *irctl)
|
|||
}
|
||||
|
||||
|
||||
static struct file_operations fops = {
|
||||
static struct file_operations lirc_dev_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = lirc_dev_fop_read,
|
||||
.write = lirc_dev_fop_write,
|
||||
.poll = lirc_dev_fop_poll,
|
||||
.unlocked_ioctl = lirc_dev_fop_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = lirc_dev_fop_ioctl,
|
||||
#endif
|
||||
.open = lirc_dev_fop_open,
|
||||
.release = lirc_dev_fop_close,
|
||||
.llseek = noop_llseek,
|
||||
|
|
@ -169,19 +169,20 @@ static int lirc_cdev_add(struct irctl *ir)
|
|||
{
|
||||
int retval;
|
||||
struct lirc_driver *d = &ir->d;
|
||||
struct cdev *cdev = &cdevs[d->minor];
|
||||
|
||||
if (d->fops) {
|
||||
cdev_init(&ir->cdev, d->fops);
|
||||
ir->cdev.owner = d->owner;
|
||||
cdev_init(cdev, d->fops);
|
||||
cdev->owner = d->owner;
|
||||
} else {
|
||||
cdev_init(&ir->cdev, &fops);
|
||||
ir->cdev.owner = THIS_MODULE;
|
||||
cdev_init(cdev, &lirc_dev_fops);
|
||||
cdev->owner = THIS_MODULE;
|
||||
}
|
||||
kobject_set_name(&ir->cdev.kobj, "lirc%d", d->minor);
|
||||
kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
|
||||
|
||||
retval = cdev_add(&ir->cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
|
||||
retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
|
||||
if (retval)
|
||||
kobject_put(&ir->cdev.kobj);
|
||||
kobject_put(&cdev->kobj);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -202,6 +203,12 @@ int lirc_register_driver(struct lirc_driver *d)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!d->dev) {
|
||||
printk(KERN_ERR "%s: dev pointer not filled in!\n", __func__);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (MAX_IRCTL_DEVICES <= d->minor) {
|
||||
dev_err(d->dev, "lirc_dev: lirc_register_driver: "
|
||||
"\"minor\" must be between 0 and %d (%d)!\n",
|
||||
|
|
@ -277,7 +284,7 @@ int lirc_register_driver(struct lirc_driver *d)
|
|||
err = -ENOMEM;
|
||||
goto out_lock;
|
||||
}
|
||||
init_irctl(ir);
|
||||
lirc_irctl_init(ir);
|
||||
irctls[minor] = ir;
|
||||
d->minor = minor;
|
||||
|
||||
|
|
@ -316,7 +323,6 @@ int lirc_register_driver(struct lirc_driver *d)
|
|||
d->features = LIRC_CAN_REC_LIRCCODE;
|
||||
|
||||
ir->d = *d;
|
||||
ir->d.minor = minor;
|
||||
|
||||
device_create(lirc_class, ir->d.dev,
|
||||
MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL,
|
||||
|
|
@ -357,21 +363,28 @@ EXPORT_SYMBOL(lirc_register_driver);
|
|||
int lirc_unregister_driver(int minor)
|
||||
{
|
||||
struct irctl *ir;
|
||||
struct cdev *cdev;
|
||||
|
||||
if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
|
||||
printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
|
||||
"\"minor (%d)\" must be between 0 and %d!\n",
|
||||
minor, MAX_IRCTL_DEVICES-1);
|
||||
printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between "
|
||||
"0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1);
|
||||
return -EBADRQC;
|
||||
}
|
||||
|
||||
ir = irctls[minor];
|
||||
if (!ir) {
|
||||
printk(KERN_ERR "lirc_dev: %s: failed to get irctl struct "
|
||||
"for minor %d!\n", __func__, minor);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
cdev = &cdevs[minor];
|
||||
|
||||
mutex_lock(&lirc_dev_lock);
|
||||
|
||||
if (ir->d.minor != minor) {
|
||||
printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
|
||||
"minor (%d) device not registered!", minor);
|
||||
printk(KERN_ERR "lirc_dev: %s: minor (%d) device not "
|
||||
"registered!\n", __func__, minor);
|
||||
mutex_unlock(&lirc_dev_lock);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
|
@ -390,12 +403,11 @@ int lirc_unregister_driver(int minor)
|
|||
wake_up_interruptible(&ir->buf->wait_poll);
|
||||
mutex_lock(&ir->irctl_lock);
|
||||
ir->d.set_use_dec(ir->d.data);
|
||||
module_put(ir->d.owner);
|
||||
module_put(cdev->owner);
|
||||
mutex_unlock(&ir->irctl_lock);
|
||||
cdev_del(&ir->cdev);
|
||||
} else {
|
||||
cleanup(ir);
|
||||
cdev_del(&ir->cdev);
|
||||
lirc_irctl_cleanup(ir);
|
||||
cdev_del(cdev);
|
||||
kfree(ir);
|
||||
irctls[minor] = NULL;
|
||||
}
|
||||
|
|
@ -409,6 +421,7 @@ EXPORT_SYMBOL(lirc_unregister_driver);
|
|||
int lirc_dev_fop_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct irctl *ir;
|
||||
struct cdev *cdev;
|
||||
int retval = 0;
|
||||
|
||||
if (iminor(inode) >= MAX_IRCTL_DEVICES) {
|
||||
|
|
@ -425,7 +438,6 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
|
|||
retval = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
file->private_data = ir;
|
||||
|
||||
dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor);
|
||||
|
||||
|
|
@ -439,13 +451,14 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (try_module_get(ir->d.owner)) {
|
||||
++ir->open;
|
||||
cdev = &cdevs[iminor(inode)];
|
||||
if (try_module_get(cdev->owner)) {
|
||||
ir->open++;
|
||||
retval = ir->d.set_use_inc(ir->d.data);
|
||||
|
||||
if (retval) {
|
||||
module_put(ir->d.owner);
|
||||
--ir->open;
|
||||
module_put(cdev->owner);
|
||||
ir->open--;
|
||||
} else {
|
||||
lirc_buffer_clear(ir->buf);
|
||||
}
|
||||
|
|
@ -469,17 +482,24 @@ EXPORT_SYMBOL(lirc_dev_fop_open);
|
|||
int lirc_dev_fop_close(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct irctl *ir = irctls[iminor(inode)];
|
||||
struct cdev *cdev = &cdevs[iminor(inode)];
|
||||
|
||||
if (!ir) {
|
||||
printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor);
|
||||
|
||||
WARN_ON(mutex_lock_killable(&lirc_dev_lock));
|
||||
|
||||
--ir->open;
|
||||
ir->open--;
|
||||
if (ir->attached) {
|
||||
ir->d.set_use_dec(ir->d.data);
|
||||
module_put(ir->d.owner);
|
||||
module_put(cdev->owner);
|
||||
} else {
|
||||
cleanup(ir);
|
||||
lirc_irctl_cleanup(ir);
|
||||
cdev_del(cdev);
|
||||
irctls[ir->d.minor] = NULL;
|
||||
kfree(ir);
|
||||
}
|
||||
|
|
@ -495,6 +515,11 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
|
|||
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
|
||||
unsigned int ret;
|
||||
|
||||
if (!ir) {
|
||||
printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
|
||||
return POLLERR;
|
||||
}
|
||||
|
||||
dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
|
||||
|
||||
if (!ir->attached) {
|
||||
|
|
@ -521,9 +546,14 @@ EXPORT_SYMBOL(lirc_dev_fop_poll);
|
|||
|
||||
long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
unsigned long mode;
|
||||
__u32 mode;
|
||||
int result = 0;
|
||||
struct irctl *ir = file->private_data;
|
||||
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
|
||||
|
||||
if (!ir) {
|
||||
printk(KERN_ERR "lirc_dev: %s: no irctl found!\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
|
||||
ir->d.name, ir->d.minor, cmd);
|
||||
|
|
@ -538,7 +568,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
|
||||
switch (cmd) {
|
||||
case LIRC_GET_FEATURES:
|
||||
result = put_user(ir->d.features, (unsigned long *)arg);
|
||||
result = put_user(ir->d.features, (__u32 *)arg);
|
||||
break;
|
||||
case LIRC_GET_REC_MODE:
|
||||
if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
|
||||
|
|
@ -548,7 +578,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
|
||||
result = put_user(LIRC_REC2MODE
|
||||
(ir->d.features & LIRC_CAN_REC_MASK),
|
||||
(unsigned long *)arg);
|
||||
(__u32 *)arg);
|
||||
break;
|
||||
case LIRC_SET_REC_MODE:
|
||||
if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
|
||||
|
|
@ -556,7 +586,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
}
|
||||
|
||||
result = get_user(mode, (unsigned long *)arg);
|
||||
result = get_user(mode, (__u32 *)arg);
|
||||
if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
|
||||
result = -EINVAL;
|
||||
/*
|
||||
|
|
@ -565,7 +595,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
*/
|
||||
break;
|
||||
case LIRC_GET_LENGTH:
|
||||
result = put_user(ir->d.code_length, (unsigned long *)arg);
|
||||
result = put_user(ir->d.code_length, (__u32 *)arg);
|
||||
break;
|
||||
case LIRC_GET_MIN_TIMEOUT:
|
||||
if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
|
||||
|
|
@ -574,7 +604,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
}
|
||||
|
||||
result = put_user(ir->d.min_timeout, (unsigned long *)arg);
|
||||
result = put_user(ir->d.min_timeout, (__u32 *)arg);
|
||||
break;
|
||||
case LIRC_GET_MAX_TIMEOUT:
|
||||
if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
|
||||
|
|
@ -583,7 +613,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
}
|
||||
|
||||
result = put_user(ir->d.max_timeout, (unsigned long *)arg);
|
||||
result = put_user(ir->d.max_timeout, (__u32 *)arg);
|
||||
break;
|
||||
default:
|
||||
result = -EINVAL;
|
||||
|
|
@ -604,12 +634,21 @@ ssize_t lirc_dev_fop_read(struct file *file,
|
|||
loff_t *ppos)
|
||||
{
|
||||
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
|
||||
unsigned char buf[ir->chunk_size];
|
||||
unsigned char *buf;
|
||||
int ret = 0, written = 0;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
|
||||
if (!ir) {
|
||||
printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor);
|
||||
|
||||
buf = kzalloc(ir->chunk_size, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
if (mutex_lock_interruptible(&ir->irctl_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (!ir->attached) {
|
||||
|
|
@ -681,6 +720,7 @@ ssize_t lirc_dev_fop_read(struct file *file,
|
|||
mutex_unlock(&ir->irctl_lock);
|
||||
|
||||
out_unlocked:
|
||||
kfree(buf);
|
||||
dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
|
||||
ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
|
||||
|
||||
|
|
@ -709,6 +749,11 @@ ssize_t lirc_dev_fop_write(struct file *file, const char *buffer,
|
|||
{
|
||||
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
|
||||
|
||||
if (!ir) {
|
||||
printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor);
|
||||
|
||||
if (!ir->attached)
|
||||
|
|
|
|||
|
|
@ -46,24 +46,58 @@
|
|||
"device driver"
|
||||
#define DRIVER_NAME "mceusb"
|
||||
|
||||
#define USB_BUFLEN 32 /* USB reception buffer length */
|
||||
#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
|
||||
#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
|
||||
#define USB_BUFLEN 32 /* USB reception buffer length */
|
||||
#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
|
||||
#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
|
||||
|
||||
/* MCE constants */
|
||||
#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
|
||||
#define MCE_TIME_UNIT 50 /* Approx 50us resolution */
|
||||
#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */
|
||||
#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */
|
||||
#define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */
|
||||
#define MCE_CONTROL_HEADER 0x9F /* MCE status header */
|
||||
#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */
|
||||
#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */
|
||||
#define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */
|
||||
#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */
|
||||
#define MCE_PULSE_MASK 0x7F /* Pulse mask */
|
||||
#define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */
|
||||
#define MCE_PACKET_LENGTH_MASK 0x1F /* Packet length mask */
|
||||
#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
|
||||
#define MCE_TIME_UNIT 50 /* Approx 50us resolution */
|
||||
#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */
|
||||
#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */
|
||||
#define MCE_IRDATA_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */
|
||||
#define MCE_IRDATA_TRAILER 0x80 /* End of IR data */
|
||||
#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */
|
||||
#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */
|
||||
#define MCE_DEFAULT_TX_MASK 0x03 /* Vals: TX1=0x01, TX2=0x02, ALL=0x03 */
|
||||
#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */
|
||||
#define MCE_PULSE_MASK 0x7f /* Pulse mask */
|
||||
#define MCE_MAX_PULSE_LENGTH 0x7f /* Longest transmittable pulse symbol */
|
||||
|
||||
#define MCE_HW_CMD_HEADER 0xff /* MCE hardware command header */
|
||||
#define MCE_COMMAND_HEADER 0x9f /* MCE command header */
|
||||
#define MCE_COMMAND_MASK 0xe0 /* Mask out command bits */
|
||||
#define MCE_COMMAND_NULL 0x00 /* These show up various places... */
|
||||
/* if buf[i] & MCE_COMMAND_MASK == 0x80 and buf[i] != MCE_COMMAND_HEADER,
|
||||
* then we're looking at a raw IR data sample */
|
||||
#define MCE_COMMAND_IRDATA 0x80
|
||||
#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
|
||||
|
||||
/* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */
|
||||
#define MCE_CMD_PING 0x03 /* Ping device */
|
||||
#define MCE_CMD_UNKNOWN 0x04 /* Unknown */
|
||||
#define MCE_CMD_UNKNOWN2 0x05 /* Unknown */
|
||||
#define MCE_CMD_S_CARRIER 0x06 /* Set TX carrier frequency */
|
||||
#define MCE_CMD_G_CARRIER 0x07 /* Get TX carrier frequency */
|
||||
#define MCE_CMD_S_TXMASK 0x08 /* Set TX port bitmask */
|
||||
#define MCE_CMD_UNKNOWN3 0x09 /* Unknown */
|
||||
#define MCE_CMD_UNKNOWN4 0x0a /* Unknown */
|
||||
#define MCE_CMD_G_REVISION 0x0b /* Get hw/sw revision */
|
||||
#define MCE_CMD_S_TIMEOUT 0x0c /* Set RX timeout value */
|
||||
#define MCE_CMD_G_TIMEOUT 0x0d /* Get RX timeout value */
|
||||
#define MCE_CMD_UNKNOWN5 0x0e /* Unknown */
|
||||
#define MCE_CMD_UNKNOWN6 0x0f /* Unknown */
|
||||
#define MCE_CMD_G_RXPORTSTS 0x11 /* Get RX port status */
|
||||
#define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */
|
||||
#define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */
|
||||
#define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */
|
||||
#define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */
|
||||
#define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */
|
||||
#define MCE_CMD_UNKNOWN7 0x18 /* Unknown */
|
||||
#define MCE_CMD_UNKNOWN8 0x19 /* Unknown */
|
||||
#define MCE_CMD_UNKNOWN9 0x1b /* Unknown */
|
||||
#define MCE_CMD_DEVICE_RESET 0xaa /* Reset the hardware */
|
||||
#define MCE_RSP_CMD_INVALID 0xfe /* Invalid command issued */
|
||||
|
||||
|
||||
/* module parameters */
|
||||
|
|
@ -104,14 +138,64 @@ static int debug;
|
|||
#define VENDOR_NORTHSTAR 0x04eb
|
||||
#define VENDOR_REALTEK 0x0bda
|
||||
#define VENDOR_TIVO 0x105a
|
||||
#define VENDOR_CONEXANT 0x0572
|
||||
|
||||
enum mceusb_model_type {
|
||||
MCE_GEN2 = 0, /* Most boards */
|
||||
MCE_GEN1,
|
||||
MCE_GEN3,
|
||||
MCE_GEN2_TX_INV,
|
||||
POLARIS_EVK,
|
||||
};
|
||||
|
||||
struct mceusb_model {
|
||||
u32 mce_gen1:1;
|
||||
u32 mce_gen2:1;
|
||||
u32 mce_gen3:1;
|
||||
u32 tx_mask_inverted:1;
|
||||
u32 is_polaris:1;
|
||||
|
||||
const char *rc_map; /* Allow specify a per-board map */
|
||||
const char *name; /* per-board name */
|
||||
};
|
||||
|
||||
static const struct mceusb_model mceusb_model[] = {
|
||||
[MCE_GEN1] = {
|
||||
.mce_gen1 = 1,
|
||||
.tx_mask_inverted = 1,
|
||||
},
|
||||
[MCE_GEN2] = {
|
||||
.mce_gen2 = 1,
|
||||
},
|
||||
[MCE_GEN2_TX_INV] = {
|
||||
.mce_gen2 = 1,
|
||||
.tx_mask_inverted = 1,
|
||||
},
|
||||
[MCE_GEN3] = {
|
||||
.mce_gen3 = 1,
|
||||
.tx_mask_inverted = 1,
|
||||
},
|
||||
[POLARIS_EVK] = {
|
||||
.is_polaris = 1,
|
||||
/*
|
||||
* In fact, the EVK is shipped without
|
||||
* remotes, but we should have something handy,
|
||||
* to allow testing it
|
||||
*/
|
||||
.rc_map = RC_MAP_RC5_HAUPPAUGE_NEW,
|
||||
.name = "cx231xx MCE IR",
|
||||
},
|
||||
};
|
||||
|
||||
static struct usb_device_id mceusb_dev_table[] = {
|
||||
/* Original Microsoft MCE IR Transceiver (often HP-branded) */
|
||||
{ USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
|
||||
{ USB_DEVICE(VENDOR_MICROSOFT, 0x006d),
|
||||
.driver_info = MCE_GEN1 },
|
||||
/* Philips Infrared Transceiver - Sahara branded */
|
||||
{ USB_DEVICE(VENDOR_PHILIPS, 0x0608) },
|
||||
/* Philips Infrared Transceiver - HP branded */
|
||||
{ USB_DEVICE(VENDOR_PHILIPS, 0x060c) },
|
||||
{ USB_DEVICE(VENDOR_PHILIPS, 0x060c),
|
||||
.driver_info = MCE_GEN2_TX_INV },
|
||||
/* Philips SRM5100 */
|
||||
{ USB_DEVICE(VENDOR_PHILIPS, 0x060d) },
|
||||
/* Philips Infrared Transceiver - Omaura */
|
||||
|
|
@ -127,11 +211,14 @@ static struct usb_device_id mceusb_dev_table[] = {
|
|||
/* Realtek MCE IR Receiver */
|
||||
{ USB_DEVICE(VENDOR_REALTEK, 0x0161) },
|
||||
/* SMK/Toshiba G83C0004D410 */
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x031d) },
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x031d),
|
||||
.driver_info = MCE_GEN2_TX_INV },
|
||||
/* SMK eHome Infrared Transceiver (Sony VAIO) */
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x0322) },
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x0322),
|
||||
.driver_info = MCE_GEN2_TX_INV },
|
||||
/* bundled with Hauppauge PVR-150 */
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x0334) },
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x0334),
|
||||
.driver_info = MCE_GEN2_TX_INV },
|
||||
/* SMK eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x0338) },
|
||||
/* Tatung eHome Infrared Transceiver */
|
||||
|
|
@ -145,17 +232,23 @@ static struct usb_device_id mceusb_dev_table[] = {
|
|||
/* Mitsumi */
|
||||
{ USB_DEVICE(VENDOR_MITSUMI, 0x2501) },
|
||||
/* Topseed eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0001),
|
||||
.driver_info = MCE_GEN2_TX_INV },
|
||||
/* Topseed HP eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0006),
|
||||
.driver_info = MCE_GEN2_TX_INV },
|
||||
/* Topseed eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0007),
|
||||
.driver_info = MCE_GEN2_TX_INV },
|
||||
/* Topseed eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0008),
|
||||
.driver_info = MCE_GEN3 },
|
||||
/* Topseed eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x000a),
|
||||
.driver_info = MCE_GEN2_TX_INV },
|
||||
/* Topseed eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0011),
|
||||
.driver_info = MCE_GEN2_TX_INV },
|
||||
/* Ricavision internal Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_RICAVISION, 0x0010) },
|
||||
/* Itron ione Libra Q-11 */
|
||||
|
|
@ -185,7 +278,8 @@ static struct usb_device_id mceusb_dev_table[] = {
|
|||
/* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
|
||||
{ USB_DEVICE(VENDOR_FINTEK, 0x0702) },
|
||||
/* Pinnacle Remote Kit */
|
||||
{ USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
|
||||
{ USB_DEVICE(VENDOR_PINNACLE, 0x0225),
|
||||
.driver_info = MCE_GEN3 },
|
||||
/* Elitegroup Computer Systems IR */
|
||||
{ USB_DEVICE(VENDOR_ECS, 0x0f38) },
|
||||
/* Wistron Corp. eHome Infrared Receiver */
|
||||
|
|
@ -198,37 +292,13 @@ static struct usb_device_id mceusb_dev_table[] = {
|
|||
{ USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
|
||||
/* TiVo PC IR Receiver */
|
||||
{ USB_DEVICE(VENDOR_TIVO, 0x2000) },
|
||||
/* Conexant SDK */
|
||||
{ USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
|
||||
.driver_info = POLARIS_EVK },
|
||||
/* Terminating entry */
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct usb_device_id gen3_list[] = {
|
||||
{ USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct usb_device_id microsoft_gen1_list[] = {
|
||||
{ USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct usb_device_id std_tx_mask_list[] = {
|
||||
{ USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
|
||||
{ USB_DEVICE(VENDOR_PHILIPS, 0x060c) },
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x031d) },
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x0322) },
|
||||
{ USB_DEVICE(VENDOR_SMK, 0x0334) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
|
||||
{ USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
|
||||
{ USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
|
||||
{}
|
||||
};
|
||||
|
||||
/* data structure for each usb transceiver */
|
||||
struct mceusb_dev {
|
||||
/* ir-core bits */
|
||||
|
|
@ -248,8 +318,15 @@ struct mceusb_dev {
|
|||
/* buffers and dma */
|
||||
unsigned char *buf_in;
|
||||
unsigned int len_in;
|
||||
u8 cmd; /* MCE command type */
|
||||
u8 rem; /* Remaining IR data bytes in packet */
|
||||
|
||||
enum {
|
||||
CMD_HEADER = 0,
|
||||
SUBCMD,
|
||||
CMD_DATA,
|
||||
PARSE_IRDATA,
|
||||
} parser_state;
|
||||
u8 cmd, rem; /* Remaining IR data bytes in packet */
|
||||
|
||||
dma_addr_t dma_in;
|
||||
dma_addr_t dma_out;
|
||||
|
||||
|
|
@ -257,7 +334,6 @@ struct mceusb_dev {
|
|||
u32 connected:1;
|
||||
u32 tx_mask_inverted:1;
|
||||
u32 microsoft_gen1:1;
|
||||
u32 reserved:29;
|
||||
} flags;
|
||||
|
||||
/* transmit support */
|
||||
|
|
@ -267,6 +343,7 @@ struct mceusb_dev {
|
|||
|
||||
char name[128];
|
||||
char phys[64];
|
||||
enum mceusb_model_type model;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -291,43 +368,81 @@ struct mceusb_dev {
|
|||
* - SET_RX_TIMEOUT sets the receiver timeout
|
||||
* - SET_RX_SENSOR sets which receiver sensor to use
|
||||
*/
|
||||
static char DEVICE_RESET[] = {0x00, 0xff, 0xaa};
|
||||
static char GET_REVISION[] = {0xff, 0x0b};
|
||||
static char GET_UNKNOWN[] = {0xff, 0x18};
|
||||
static char GET_UNKNOWN2[] = {0x9f, 0x05};
|
||||
static char GET_CARRIER_FREQ[] = {0x9f, 0x07};
|
||||
static char GET_RX_TIMEOUT[] = {0x9f, 0x0d};
|
||||
static char GET_TX_BITMASK[] = {0x9f, 0x13};
|
||||
static char GET_RX_SENSOR[] = {0x9f, 0x15};
|
||||
static char DEVICE_RESET[] = {MCE_COMMAND_NULL, MCE_HW_CMD_HEADER,
|
||||
MCE_CMD_DEVICE_RESET};
|
||||
static char GET_REVISION[] = {MCE_HW_CMD_HEADER, MCE_CMD_G_REVISION};
|
||||
static char GET_UNKNOWN[] = {MCE_HW_CMD_HEADER, MCE_CMD_UNKNOWN7};
|
||||
static char GET_UNKNOWN2[] = {MCE_COMMAND_HEADER, MCE_CMD_UNKNOWN2};
|
||||
static char GET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, MCE_CMD_G_CARRIER};
|
||||
static char GET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TIMEOUT};
|
||||
static char GET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TXMASK};
|
||||
static char GET_RX_SENSOR[] = {MCE_COMMAND_HEADER, MCE_CMD_G_RXSENSOR};
|
||||
/* sub in desired values in lower byte or bytes for full command */
|
||||
/* FIXME: make use of these for transmit.
|
||||
static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00};
|
||||
static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00};
|
||||
static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00};
|
||||
static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00};
|
||||
static char SET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER,
|
||||
MCE_CMD_S_CARRIER, 0x00, 0x00};
|
||||
static char SET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_S_TXMASK, 0x00};
|
||||
static char SET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER,
|
||||
MCE_CMD_S_TIMEOUT, 0x00, 0x00};
|
||||
static char SET_RX_SENSOR[] = {MCE_COMMAND_HEADER,
|
||||
MCE_CMD_S_RXSENSOR, 0x00};
|
||||
*/
|
||||
|
||||
static int mceusb_cmdsize(u8 cmd, u8 subcmd)
|
||||
{
|
||||
int datasize = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case MCE_COMMAND_NULL:
|
||||
if (subcmd == MCE_HW_CMD_HEADER)
|
||||
datasize = 1;
|
||||
break;
|
||||
case MCE_HW_CMD_HEADER:
|
||||
switch (subcmd) {
|
||||
case MCE_CMD_G_REVISION:
|
||||
datasize = 2;
|
||||
break;
|
||||
}
|
||||
case MCE_COMMAND_HEADER:
|
||||
switch (subcmd) {
|
||||
case MCE_CMD_UNKNOWN:
|
||||
case MCE_CMD_S_CARRIER:
|
||||
case MCE_CMD_S_TIMEOUT:
|
||||
case MCE_CMD_G_RXSENSOR:
|
||||
datasize = 2;
|
||||
break;
|
||||
case MCE_CMD_S_TXMASK:
|
||||
case MCE_CMD_S_RXSENSOR:
|
||||
datasize = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return datasize;
|
||||
}
|
||||
|
||||
static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
||||
int len, bool out)
|
||||
int offset, int len, bool out)
|
||||
{
|
||||
char codes[USB_BUFLEN * 3 + 1];
|
||||
char inout[9];
|
||||
int i;
|
||||
u8 cmd, subcmd, data1, data2;
|
||||
struct device *dev = ir->dev;
|
||||
int idx = 0;
|
||||
int i, start, skip = 0;
|
||||
|
||||
if (!debug)
|
||||
return;
|
||||
|
||||
/* skip meaningless 0xb1 0x60 header bytes on orig receiver */
|
||||
if (ir->flags.microsoft_gen1 && !out)
|
||||
idx = 2;
|
||||
skip = 2;
|
||||
|
||||
if (len <= idx)
|
||||
if (len <= skip)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len && i < USB_BUFLEN; i++)
|
||||
snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF);
|
||||
snprintf(codes + i * 3, 4, "%02x ", buf[i + offset] & 0xff);
|
||||
|
||||
dev_info(dev, "%sx data: %s (length=%d)\n",
|
||||
dev_info(dev, "%sx data: %s(length=%d)\n",
|
||||
(out ? "t" : "r"), codes, len);
|
||||
|
||||
if (out)
|
||||
|
|
@ -335,91 +450,93 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
|||
else
|
||||
strcpy(inout, "Got\0");
|
||||
|
||||
cmd = buf[idx] & 0xff;
|
||||
subcmd = buf[idx + 1] & 0xff;
|
||||
data1 = buf[idx + 2] & 0xff;
|
||||
data2 = buf[idx + 3] & 0xff;
|
||||
start = offset + skip;
|
||||
cmd = buf[start] & 0xff;
|
||||
subcmd = buf[start + 1] & 0xff;
|
||||
data1 = buf[start + 2] & 0xff;
|
||||
data2 = buf[start + 3] & 0xff;
|
||||
|
||||
switch (cmd) {
|
||||
case 0x00:
|
||||
if (subcmd == 0xff && data1 == 0xaa)
|
||||
case MCE_COMMAND_NULL:
|
||||
if ((subcmd == MCE_HW_CMD_HEADER) &&
|
||||
(data1 == MCE_CMD_DEVICE_RESET))
|
||||
dev_info(dev, "Device reset requested\n");
|
||||
else
|
||||
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
|
||||
cmd, subcmd);
|
||||
break;
|
||||
case 0xff:
|
||||
case MCE_HW_CMD_HEADER:
|
||||
switch (subcmd) {
|
||||
case 0x0b:
|
||||
case MCE_CMD_G_REVISION:
|
||||
if (len == 2)
|
||||
dev_info(dev, "Get hw/sw rev?\n");
|
||||
else
|
||||
dev_info(dev, "hw/sw rev 0x%02x 0x%02x "
|
||||
"0x%02x 0x%02x\n", data1, data2,
|
||||
buf[idx + 4], buf[idx + 5]);
|
||||
buf[start + 4], buf[start + 5]);
|
||||
break;
|
||||
case 0xaa:
|
||||
case MCE_CMD_DEVICE_RESET:
|
||||
dev_info(dev, "Device reset requested\n");
|
||||
break;
|
||||
case 0xfe:
|
||||
case MCE_RSP_CMD_INVALID:
|
||||
dev_info(dev, "Previous command not supported\n");
|
||||
break;
|
||||
case 0x18:
|
||||
case 0x1b:
|
||||
case MCE_CMD_UNKNOWN7:
|
||||
case MCE_CMD_UNKNOWN9:
|
||||
default:
|
||||
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
|
||||
cmd, subcmd);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x9f:
|
||||
case MCE_COMMAND_HEADER:
|
||||
switch (subcmd) {
|
||||
case 0x03:
|
||||
case MCE_CMD_PING:
|
||||
dev_info(dev, "Ping\n");
|
||||
break;
|
||||
case 0x04:
|
||||
case MCE_CMD_UNKNOWN:
|
||||
dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n",
|
||||
data1, data2);
|
||||
break;
|
||||
case 0x06:
|
||||
case MCE_CMD_S_CARRIER:
|
||||
dev_info(dev, "%s carrier mode and freq of "
|
||||
"0x%02x 0x%02x\n", inout, data1, data2);
|
||||
break;
|
||||
case 0x07:
|
||||
case MCE_CMD_G_CARRIER:
|
||||
dev_info(dev, "Get carrier mode and freq\n");
|
||||
break;
|
||||
case 0x08:
|
||||
case MCE_CMD_S_TXMASK:
|
||||
dev_info(dev, "%s transmit blaster mask of 0x%02x\n",
|
||||
inout, data1);
|
||||
break;
|
||||
case 0x0c:
|
||||
case MCE_CMD_S_TIMEOUT:
|
||||
/* value is in units of 50us, so x*50/100 or x/2 ms */
|
||||
dev_info(dev, "%s receive timeout of %d ms\n",
|
||||
inout, ((data1 << 8) | data2) / 2);
|
||||
break;
|
||||
case 0x0d:
|
||||
case MCE_CMD_G_TIMEOUT:
|
||||
dev_info(dev, "Get receive timeout\n");
|
||||
break;
|
||||
case 0x13:
|
||||
case MCE_CMD_G_TXMASK:
|
||||
dev_info(dev, "Get transmit blaster mask\n");
|
||||
break;
|
||||
case 0x14:
|
||||
case MCE_CMD_S_RXSENSOR:
|
||||
dev_info(dev, "%s %s-range receive sensor in use\n",
|
||||
inout, data1 == 0x02 ? "short" : "long");
|
||||
break;
|
||||
case 0x15:
|
||||
case MCE_CMD_G_RXSENSOR:
|
||||
if (len == 2)
|
||||
dev_info(dev, "Get receive sensor\n");
|
||||
else
|
||||
dev_info(dev, "Received pulse count is %d\n",
|
||||
((data1 << 8) | data2));
|
||||
break;
|
||||
case 0xfe:
|
||||
case MCE_RSP_CMD_INVALID:
|
||||
dev_info(dev, "Error! Hardware is likely wedged...\n");
|
||||
break;
|
||||
case 0x05:
|
||||
case 0x09:
|
||||
case 0x0f:
|
||||
case MCE_CMD_UNKNOWN2:
|
||||
case MCE_CMD_UNKNOWN3:
|
||||
case MCE_CMD_UNKNOWN5:
|
||||
default:
|
||||
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
|
||||
cmd, subcmd);
|
||||
|
|
@ -429,6 +546,12 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd == MCE_IRDATA_TRAILER)
|
||||
dev_info(dev, "End of raw IR data\n");
|
||||
else if ((cmd != MCE_COMMAND_HEADER) &&
|
||||
((cmd & MCE_COMMAND_MASK) == MCE_COMMAND_IRDATA))
|
||||
dev_info(dev, "Raw IR data, %d pulse/space samples\n", ir->rem);
|
||||
}
|
||||
|
||||
static void mce_async_callback(struct urb *urb, struct pt_regs *regs)
|
||||
|
|
@ -446,9 +569,7 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs)
|
|||
dev_dbg(ir->dev, "callback called (status=%d len=%d)\n",
|
||||
urb->status, len);
|
||||
|
||||
if (debug)
|
||||
mceusb_dev_printdata(ir, urb->transfer_buffer,
|
||||
len, true);
|
||||
mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -536,8 +657,8 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
|
|||
return -ENOMEM;
|
||||
|
||||
/* MCE tx init header */
|
||||
cmdbuf[cmdcount++] = MCE_CONTROL_HEADER;
|
||||
cmdbuf[cmdcount++] = 0x08;
|
||||
cmdbuf[cmdcount++] = MCE_COMMAND_HEADER;
|
||||
cmdbuf[cmdcount++] = MCE_CMD_S_TXMASK;
|
||||
cmdbuf[cmdcount++] = ir->tx_mask;
|
||||
|
||||
/* Generate mce packet data */
|
||||
|
|
@ -551,7 +672,7 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
|
|||
if ((cmdcount < MCE_CMDBUF_SIZE) &&
|
||||
(cmdcount - MCE_TX_HEADER_LENGTH) %
|
||||
MCE_CODE_LENGTH == 0)
|
||||
cmdbuf[cmdcount++] = MCE_PACKET_HEADER;
|
||||
cmdbuf[cmdcount++] = MCE_IRDATA_HEADER;
|
||||
|
||||
/* Insert mce packet data */
|
||||
if (cmdcount < MCE_CMDBUF_SIZE)
|
||||
|
|
@ -570,7 +691,8 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
|
|||
|
||||
/* Fix packet length in last header */
|
||||
cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] =
|
||||
0x80 + (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH - 1;
|
||||
MCE_COMMAND_IRDATA + (cmdcount - MCE_TX_HEADER_LENGTH) %
|
||||
MCE_CODE_LENGTH - 1;
|
||||
|
||||
/* Check if we have room for the empty packet at the end */
|
||||
if (cmdcount >= MCE_CMDBUF_SIZE) {
|
||||
|
|
@ -579,7 +701,7 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
|
|||
}
|
||||
|
||||
/* All mce commands end with an empty packet (0x80) */
|
||||
cmdbuf[cmdcount++] = 0x80;
|
||||
cmdbuf[cmdcount++] = MCE_IRDATA_TRAILER;
|
||||
|
||||
/* Transmit the command to the mce device */
|
||||
mce_async_out(ir, cmdbuf, cmdcount);
|
||||
|
|
@ -608,7 +730,8 @@ static int mceusb_set_tx_mask(void *priv, u32 mask)
|
|||
struct mceusb_dev *ir = priv;
|
||||
|
||||
if (ir->flags.tx_mask_inverted)
|
||||
ir->tx_mask = (mask != 0x03 ? mask ^ 0x03 : mask) << 1;
|
||||
ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ?
|
||||
mask ^ MCE_DEFAULT_TX_MASK : mask) << 1;
|
||||
else
|
||||
ir->tx_mask = mask;
|
||||
|
||||
|
|
@ -621,7 +744,8 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
|
|||
struct mceusb_dev *ir = priv;
|
||||
int clk = 10000000;
|
||||
int prescaler = 0, divisor = 0;
|
||||
unsigned char cmdbuf[4] = { 0x9f, 0x06, 0x00, 0x00 };
|
||||
unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER,
|
||||
MCE_CMD_S_CARRIER, 0x00, 0x00 };
|
||||
|
||||
/* Carrier has changed */
|
||||
if (ir->carrier != carrier) {
|
||||
|
|
@ -629,7 +753,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
|
|||
if (carrier == 0) {
|
||||
ir->carrier = carrier;
|
||||
cmdbuf[2] = 0x01;
|
||||
cmdbuf[3] = 0x80;
|
||||
cmdbuf[3] = MCE_IRDATA_TRAILER;
|
||||
dev_dbg(ir->dev, "%s: disabling carrier "
|
||||
"modulation\n", __func__);
|
||||
mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
|
||||
|
|
@ -638,7 +762,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
|
|||
|
||||
for (prescaler = 0; prescaler < 4; ++prescaler) {
|
||||
divisor = (clk >> (2 * prescaler)) / carrier;
|
||||
if (divisor <= 0xFF) {
|
||||
if (divisor <= 0xff) {
|
||||
ir->carrier = carrier;
|
||||
cmdbuf[2] = prescaler;
|
||||
cmdbuf[3] = divisor;
|
||||
|
|
@ -660,47 +784,36 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
|
|||
|
||||
static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
|
||||
{
|
||||
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
|
||||
int i, start_index = 0;
|
||||
u8 hdr = MCE_CONTROL_HEADER;
|
||||
DEFINE_IR_RAW_EVENT(rawir);
|
||||
int i = 0;
|
||||
|
||||
/* skip meaningless 0xb1 0x60 header bytes on orig receiver */
|
||||
if (ir->flags.microsoft_gen1)
|
||||
start_index = 2;
|
||||
i = 2;
|
||||
|
||||
for (i = start_index; i < buf_len;) {
|
||||
if (ir->rem == 0) {
|
||||
/* decode mce packets of the form (84),AA,BB,CC,DD */
|
||||
/* IR data packets can span USB messages - rem */
|
||||
hdr = ir->buf_in[i];
|
||||
ir->rem = (hdr & MCE_PACKET_LENGTH_MASK);
|
||||
ir->cmd = (hdr & ~MCE_PACKET_LENGTH_MASK);
|
||||
dev_dbg(ir->dev, "New data. rem: 0x%02x, cmd: 0x%02x\n",
|
||||
ir->rem, ir->cmd);
|
||||
i++;
|
||||
}
|
||||
|
||||
/* don't process MCE commands */
|
||||
if (hdr == MCE_CONTROL_HEADER || hdr == 0xff) {
|
||||
ir->rem = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (; (ir->rem > 0) && (i < buf_len); i++) {
|
||||
for (; i < buf_len; i++) {
|
||||
switch (ir->parser_state) {
|
||||
case SUBCMD:
|
||||
ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]);
|
||||
mceusb_dev_printdata(ir, ir->buf_in, i - 1,
|
||||
ir->rem + 2, false);
|
||||
ir->parser_state = CMD_DATA;
|
||||
break;
|
||||
case PARSE_IRDATA:
|
||||
ir->rem--;
|
||||
|
||||
rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
|
||||
rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
|
||||
* MCE_TIME_UNIT * 1000;
|
||||
|
||||
if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
|
||||
if (ir->rawir.pulse == rawir.pulse)
|
||||
if (ir->rawir.pulse == rawir.pulse) {
|
||||
ir->rawir.duration += rawir.duration;
|
||||
else {
|
||||
} else {
|
||||
ir->rawir.duration = rawir.duration;
|
||||
ir->rawir.pulse = rawir.pulse;
|
||||
}
|
||||
continue;
|
||||
if (ir->rem)
|
||||
break;
|
||||
}
|
||||
rawir.duration += ir->rawir.duration;
|
||||
ir->rawir.duration = 0;
|
||||
|
|
@ -711,14 +824,40 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
|
|||
rawir.duration);
|
||||
|
||||
ir_raw_event_store(ir->idev, &rawir);
|
||||
break;
|
||||
case CMD_DATA:
|
||||
ir->rem--;
|
||||
break;
|
||||
case CMD_HEADER:
|
||||
/* decode mce packets of the form (84),AA,BB,CC,DD */
|
||||
/* IR data packets can span USB messages - rem */
|
||||
ir->cmd = ir->buf_in[i];
|
||||
if ((ir->cmd == MCE_COMMAND_HEADER) ||
|
||||
((ir->cmd & MCE_COMMAND_MASK) !=
|
||||
MCE_COMMAND_IRDATA)) {
|
||||
ir->parser_state = SUBCMD;
|
||||
continue;
|
||||
}
|
||||
ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK);
|
||||
mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false);
|
||||
if (ir->rem) {
|
||||
ir->parser_state = PARSE_IRDATA;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* a package with len=0 (e. g. 0x80) means end of
|
||||
* data. We could use it to do the call to
|
||||
* ir_raw_event_handle(). For now, we don't need to
|
||||
* use it.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
if (ir->buf_in[i] == 0x80 || ir->buf_in[i] == 0x9f)
|
||||
ir->rem = 0;
|
||||
|
||||
dev_dbg(ir->dev, "calling ir_raw_event_handle\n");
|
||||
ir_raw_event_handle(ir->idev);
|
||||
if (ir->parser_state != CMD_HEADER && !ir->rem)
|
||||
ir->parser_state = CMD_HEADER;
|
||||
}
|
||||
dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
|
||||
ir_raw_event_handle(ir->idev);
|
||||
}
|
||||
|
||||
static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
|
||||
|
|
@ -737,9 +876,6 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
|
|||
|
||||
buf_len = urb->actual_length;
|
||||
|
||||
if (debug)
|
||||
mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false);
|
||||
|
||||
if (ir->send_flags == RECV_FLAG_IN_PROGRESS) {
|
||||
ir->send_flags = SEND_FLAG_COMPLETE;
|
||||
dev_dbg(ir->dev, "setup answer received %d bytes\n",
|
||||
|
|
@ -760,6 +896,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
|
|||
|
||||
case -EPIPE:
|
||||
default:
|
||||
dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -865,6 +1002,8 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
|
|||
struct input_dev *idev;
|
||||
struct ir_dev_props *props;
|
||||
struct device *dev = ir->dev;
|
||||
const char *rc_map = RC_MAP_RC6_MCE;
|
||||
const char *name = "Media Center Ed. eHome Infrared Remote Transceiver";
|
||||
int ret = -ENODEV;
|
||||
|
||||
idev = input_allocate_device();
|
||||
|
|
@ -880,8 +1019,11 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
|
|||
goto props_alloc_failed;
|
||||
}
|
||||
|
||||
snprintf(ir->name, sizeof(ir->name), "Media Center Ed. eHome "
|
||||
"Infrared Remote Transceiver (%04x:%04x)",
|
||||
if (mceusb_model[ir->model].name)
|
||||
name = mceusb_model[ir->model].name;
|
||||
|
||||
snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)",
|
||||
name,
|
||||
le16_to_cpu(ir->usbdev->descriptor.idVendor),
|
||||
le16_to_cpu(ir->usbdev->descriptor.idProduct));
|
||||
|
||||
|
|
@ -899,7 +1041,10 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
|
|||
|
||||
ir->props = props;
|
||||
|
||||
ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME);
|
||||
if (mceusb_model[ir->model].rc_map)
|
||||
rc_map = mceusb_model[ir->model].rc_map;
|
||||
|
||||
ret = ir_input_register(idev, rc_map, props, DRIVER_NAME);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "remote input device register failed\n");
|
||||
goto irdev_failed;
|
||||
|
|
@ -926,17 +1071,26 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
|
|||
struct mceusb_dev *ir = NULL;
|
||||
int pipe, maxp, i;
|
||||
char buf[63], name[128] = "";
|
||||
enum mceusb_model_type model = id->driver_info;
|
||||
bool is_gen3;
|
||||
bool is_microsoft_gen1;
|
||||
bool tx_mask_inverted;
|
||||
bool is_polaris;
|
||||
|
||||
dev_dbg(&intf->dev, ": %s called\n", __func__);
|
||||
|
||||
idesc = intf->cur_altsetting;
|
||||
|
||||
is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0;
|
||||
is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0;
|
||||
tx_mask_inverted = usb_match_id(intf, std_tx_mask_list) ? 0 : 1;
|
||||
is_gen3 = mceusb_model[model].mce_gen3;
|
||||
is_microsoft_gen1 = mceusb_model[model].mce_gen1;
|
||||
tx_mask_inverted = mceusb_model[model].tx_mask_inverted;
|
||||
is_polaris = mceusb_model[model].is_polaris;
|
||||
|
||||
if (is_polaris) {
|
||||
/* Interface 0 is IR */
|
||||
if (idesc->desc.bInterfaceNumber)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* step through the endpoints to find first bulk in and out endpoint */
|
||||
for (i = 0; i < idesc->desc.bNumEndpoints; ++i) {
|
||||
|
|
@ -997,6 +1151,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
|
|||
ir->len_in = maxp;
|
||||
ir->flags.microsoft_gen1 = is_microsoft_gen1;
|
||||
ir->flags.tx_mask_inverted = tx_mask_inverted;
|
||||
ir->model = model;
|
||||
|
||||
init_ir_raw_event(&ir->rawir);
|
||||
|
||||
/* Saving usb interface data for use by the transmitter routine */
|
||||
ir->usb_ep_in = ep_in;
|
||||
|
|
|
|||
1246
drivers/media/IR/nuvoton-cir.c
Normal file
1246
drivers/media/IR/nuvoton-cir.c
Normal file
File diff suppressed because it is too large
Load diff
408
drivers/media/IR/nuvoton-cir.h
Normal file
408
drivers/media/IR/nuvoton-cir.h
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* Driver for Nuvoton Technology Corporation w83667hg/w83677hg-i CIR
|
||||
*
|
||||
* Copyright (C) 2010 Jarod Wilson <jarod@redhat.com>
|
||||
* Copyright (C) 2009 Nuvoton PS Team
|
||||
*
|
||||
* Special thanks to Nuvoton for providing hardware, spec sheets and
|
||||
* sample code upon which portions of this driver are based. Indirect
|
||||
* thanks also to Maxim Levitsky, whose ene_ir driver this driver is
|
||||
* modeled after.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*/
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
/* platform driver name to register */
|
||||
#define NVT_DRIVER_NAME "nuvoton-cir"
|
||||
|
||||
/* debugging module parameter */
|
||||
static int debug;
|
||||
|
||||
|
||||
#define nvt_pr(level, text, ...) \
|
||||
printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__)
|
||||
|
||||
#define nvt_dbg(text, ...) \
|
||||
if (debug) \
|
||||
printk(KERN_DEBUG \
|
||||
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
|
||||
|
||||
#define nvt_dbg_verbose(text, ...) \
|
||||
if (debug > 1) \
|
||||
printk(KERN_DEBUG \
|
||||
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
|
||||
|
||||
#define nvt_dbg_wake(text, ...) \
|
||||
if (debug > 2) \
|
||||
printk(KERN_DEBUG \
|
||||
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
|
||||
|
||||
|
||||
/*
|
||||
* Original lirc driver said min value of 76, and recommended value of 256
|
||||
* for the buffer length, but then used 2048. Never mind that the size of the
|
||||
* RX FIFO is 32 bytes... So I'm using 32 for RX and 256 for TX atm, but I'm
|
||||
* not sure if maybe that TX value is off by a factor of 8 (bits vs. bytes),
|
||||
* and I don't have TX-capable hardware to test/debug on...
|
||||
*/
|
||||
#define TX_BUF_LEN 256
|
||||
#define RX_BUF_LEN 32
|
||||
|
||||
struct nvt_dev {
|
||||
struct pnp_dev *pdev;
|
||||
struct input_dev *rdev;
|
||||
struct ir_dev_props *props;
|
||||
struct ir_raw_event rawir;
|
||||
|
||||
spinlock_t nvt_lock;
|
||||
bool in_use;
|
||||
|
||||
/* for rx */
|
||||
u8 buf[RX_BUF_LEN];
|
||||
unsigned int pkts;
|
||||
|
||||
struct {
|
||||
spinlock_t lock;
|
||||
u8 buf[TX_BUF_LEN];
|
||||
unsigned int buf_count;
|
||||
unsigned int cur_buf_num;
|
||||
wait_queue_head_t queue;
|
||||
u8 tx_state;
|
||||
} tx;
|
||||
|
||||
/* EFER Config register index/data pair */
|
||||
u8 cr_efir;
|
||||
u8 cr_efdr;
|
||||
|
||||
/* hardware I/O settings */
|
||||
unsigned long cir_addr;
|
||||
unsigned long cir_wake_addr;
|
||||
int cir_irq;
|
||||
int cir_wake_irq;
|
||||
|
||||
/* hardware id */
|
||||
u8 chip_major;
|
||||
u8 chip_minor;
|
||||
|
||||
/* hardware features */
|
||||
bool hw_learning_capable;
|
||||
bool hw_tx_capable;
|
||||
|
||||
/* rx settings */
|
||||
bool learning_enabled;
|
||||
bool carrier_detect_enabled;
|
||||
|
||||
/* track cir wake state */
|
||||
u8 wake_state;
|
||||
/* for study */
|
||||
u8 study_state;
|
||||
/* carrier period = 1 / frequency */
|
||||
u32 carrier;
|
||||
};
|
||||
|
||||
/* study states */
|
||||
#define ST_STUDY_NONE 0x0
|
||||
#define ST_STUDY_START 0x1
|
||||
#define ST_STUDY_CARRIER 0x2
|
||||
#define ST_STUDY_ALL_RECV 0x4
|
||||
|
||||
/* wake states */
|
||||
#define ST_WAKE_NONE 0x0
|
||||
#define ST_WAKE_START 0x1
|
||||
#define ST_WAKE_FINISH 0x2
|
||||
|
||||
/* receive states */
|
||||
#define ST_RX_WAIT_7F 0x1
|
||||
#define ST_RX_WAIT_HEAD 0x2
|
||||
#define ST_RX_WAIT_SILENT_END 0x4
|
||||
|
||||
/* send states */
|
||||
#define ST_TX_NONE 0x0
|
||||
#define ST_TX_REQUEST 0x2
|
||||
#define ST_TX_REPLY 0x4
|
||||
|
||||
/* buffer packet constants */
|
||||
#define BUF_PULSE_BIT 0x80
|
||||
#define BUF_LEN_MASK 0x7f
|
||||
#define BUF_REPEAT_BYTE 0x70
|
||||
#define BUF_REPEAT_MASK 0xf0
|
||||
|
||||
/* CIR settings */
|
||||
|
||||
/* total length of CIR and CIR WAKE */
|
||||
#define CIR_IOREG_LENGTH 0x0f
|
||||
|
||||
/* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL (0x7d0 = 2000) */
|
||||
#define CIR_RX_LIMIT_COUNT 0x7d0
|
||||
|
||||
/* CIR Regs */
|
||||
#define CIR_IRCON 0x00
|
||||
#define CIR_IRSTS 0x01
|
||||
#define CIR_IREN 0x02
|
||||
#define CIR_RXFCONT 0x03
|
||||
#define CIR_CP 0x04
|
||||
#define CIR_CC 0x05
|
||||
#define CIR_SLCH 0x06
|
||||
#define CIR_SLCL 0x07
|
||||
#define CIR_FIFOCON 0x08
|
||||
#define CIR_IRFIFOSTS 0x09
|
||||
#define CIR_SRXFIFO 0x0a
|
||||
#define CIR_TXFCONT 0x0b
|
||||
#define CIR_STXFIFO 0x0c
|
||||
#define CIR_FCCH 0x0d
|
||||
#define CIR_FCCL 0x0e
|
||||
#define CIR_IRFSM 0x0f
|
||||
|
||||
/* CIR IRCON settings */
|
||||
#define CIR_IRCON_RECV 0x80
|
||||
#define CIR_IRCON_WIREN 0x40
|
||||
#define CIR_IRCON_TXEN 0x20
|
||||
#define CIR_IRCON_RXEN 0x10
|
||||
#define CIR_IRCON_WRXINV 0x08
|
||||
#define CIR_IRCON_RXINV 0x04
|
||||
|
||||
#define CIR_IRCON_SAMPLE_PERIOD_SEL_1 0x00
|
||||
#define CIR_IRCON_SAMPLE_PERIOD_SEL_25 0x01
|
||||
#define CIR_IRCON_SAMPLE_PERIOD_SEL_50 0x02
|
||||
#define CIR_IRCON_SAMPLE_PERIOD_SEL_100 0x03
|
||||
|
||||
/* FIXME: make this a runtime option */
|
||||
/* select sample period as 50us */
|
||||
#define CIR_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50
|
||||
|
||||
/* CIR IRSTS settings */
|
||||
#define CIR_IRSTS_RDR 0x80
|
||||
#define CIR_IRSTS_RTR 0x40
|
||||
#define CIR_IRSTS_PE 0x20
|
||||
#define CIR_IRSTS_RFO 0x10
|
||||
#define CIR_IRSTS_TE 0x08
|
||||
#define CIR_IRSTS_TTR 0x04
|
||||
#define CIR_IRSTS_TFU 0x02
|
||||
#define CIR_IRSTS_GH 0x01
|
||||
|
||||
/* CIR IREN settings */
|
||||
#define CIR_IREN_RDR 0x80
|
||||
#define CIR_IREN_RTR 0x40
|
||||
#define CIR_IREN_PE 0x20
|
||||
#define CIR_IREN_RFO 0x10
|
||||
#define CIR_IREN_TE 0x08
|
||||
#define CIR_IREN_TTR 0x04
|
||||
#define CIR_IREN_TFU 0x02
|
||||
#define CIR_IREN_GH 0x01
|
||||
|
||||
/* CIR FIFOCON settings */
|
||||
#define CIR_FIFOCON_TXFIFOCLR 0x80
|
||||
|
||||
#define CIR_FIFOCON_TX_TRIGGER_LEV_31 0x00
|
||||
#define CIR_FIFOCON_TX_TRIGGER_LEV_24 0x10
|
||||
#define CIR_FIFOCON_TX_TRIGGER_LEV_16 0x20
|
||||
#define CIR_FIFOCON_TX_TRIGGER_LEV_8 0x30
|
||||
|
||||
/* FIXME: make this a runtime option */
|
||||
/* select TX trigger level as 16 */
|
||||
#define CIR_FIFOCON_TX_TRIGGER_LEV CIR_FIFOCON_TX_TRIGGER_LEV_16
|
||||
|
||||
#define CIR_FIFOCON_RXFIFOCLR 0x08
|
||||
|
||||
#define CIR_FIFOCON_RX_TRIGGER_LEV_1 0x00
|
||||
#define CIR_FIFOCON_RX_TRIGGER_LEV_8 0x01
|
||||
#define CIR_FIFOCON_RX_TRIGGER_LEV_16 0x02
|
||||
#define CIR_FIFOCON_RX_TRIGGER_LEV_24 0x03
|
||||
|
||||
/* FIXME: make this a runtime option */
|
||||
/* select RX trigger level as 24 */
|
||||
#define CIR_FIFOCON_RX_TRIGGER_LEV CIR_FIFOCON_RX_TRIGGER_LEV_24
|
||||
|
||||
/* CIR IRFIFOSTS settings */
|
||||
#define CIR_IRFIFOSTS_IR_PENDING 0x80
|
||||
#define CIR_IRFIFOSTS_RX_GS 0x40
|
||||
#define CIR_IRFIFOSTS_RX_FTA 0x20
|
||||
#define CIR_IRFIFOSTS_RX_EMPTY 0x10
|
||||
#define CIR_IRFIFOSTS_RX_FULL 0x08
|
||||
#define CIR_IRFIFOSTS_TX_FTA 0x04
|
||||
#define CIR_IRFIFOSTS_TX_EMPTY 0x02
|
||||
#define CIR_IRFIFOSTS_TX_FULL 0x01
|
||||
|
||||
|
||||
/* CIR WAKE UP Regs */
|
||||
#define CIR_WAKE_IRCON 0x00
|
||||
#define CIR_WAKE_IRSTS 0x01
|
||||
#define CIR_WAKE_IREN 0x02
|
||||
#define CIR_WAKE_FIFO_CMP_DEEP 0x03
|
||||
#define CIR_WAKE_FIFO_CMP_TOL 0x04
|
||||
#define CIR_WAKE_FIFO_COUNT 0x05
|
||||
#define CIR_WAKE_SLCH 0x06
|
||||
#define CIR_WAKE_SLCL 0x07
|
||||
#define CIR_WAKE_FIFOCON 0x08
|
||||
#define CIR_WAKE_SRXFSTS 0x09
|
||||
#define CIR_WAKE_SAMPLE_RX_FIFO 0x0a
|
||||
#define CIR_WAKE_WR_FIFO_DATA 0x0b
|
||||
#define CIR_WAKE_RD_FIFO_ONLY 0x0c
|
||||
#define CIR_WAKE_RD_FIFO_ONLY_IDX 0x0d
|
||||
#define CIR_WAKE_FIFO_IGNORE 0x0e
|
||||
#define CIR_WAKE_IRFSM 0x0f
|
||||
|
||||
/* CIR WAKE UP IRCON settings */
|
||||
#define CIR_WAKE_IRCON_DEC_RST 0x80
|
||||
#define CIR_WAKE_IRCON_MODE1 0x40
|
||||
#define CIR_WAKE_IRCON_MODE0 0x20
|
||||
#define CIR_WAKE_IRCON_RXEN 0x10
|
||||
#define CIR_WAKE_IRCON_R 0x08
|
||||
#define CIR_WAKE_IRCON_RXINV 0x04
|
||||
|
||||
/* FIXME/jarod: make this a runtime option */
|
||||
/* select a same sample period like cir register */
|
||||
#define CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50
|
||||
|
||||
/* CIR WAKE IRSTS Bits */
|
||||
#define CIR_WAKE_IRSTS_RDR 0x80
|
||||
#define CIR_WAKE_IRSTS_RTR 0x40
|
||||
#define CIR_WAKE_IRSTS_PE 0x20
|
||||
#define CIR_WAKE_IRSTS_RFO 0x10
|
||||
#define CIR_WAKE_IRSTS_GH 0x08
|
||||
#define CIR_WAKE_IRSTS_IR_PENDING 0x01
|
||||
|
||||
/* CIR WAKE UP IREN Bits */
|
||||
#define CIR_WAKE_IREN_RDR 0x80
|
||||
#define CIR_WAKE_IREN_RTR 0x40
|
||||
#define CIR_WAKE_IREN_PE 0x20
|
||||
#define CIR_WAKE_IREN_RFO 0x10
|
||||
#define CIR_WAKE_IREN_TE 0x08
|
||||
#define CIR_WAKE_IREN_TTR 0x04
|
||||
#define CIR_WAKE_IREN_TFU 0x02
|
||||
#define CIR_WAKE_IREN_GH 0x01
|
||||
|
||||
/* CIR WAKE FIFOCON settings */
|
||||
#define CIR_WAKE_FIFOCON_RXFIFOCLR 0x08
|
||||
|
||||
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 0x00
|
||||
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_66 0x01
|
||||
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_65 0x02
|
||||
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_64 0x03
|
||||
|
||||
/* FIXME: make this a runtime option */
|
||||
/* select WAKE UP RX trigger level as 67 */
|
||||
#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67
|
||||
|
||||
/* CIR WAKE SRXFSTS settings */
|
||||
#define CIR_WAKE_IRFIFOSTS_RX_GS 0x80
|
||||
#define CIR_WAKE_IRFIFOSTS_RX_FTA 0x40
|
||||
#define CIR_WAKE_IRFIFOSTS_RX_EMPTY 0x20
|
||||
#define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10
|
||||
|
||||
/* CIR Wake FIFO buffer is 67 bytes long */
|
||||
#define CIR_WAKE_FIFO_LEN 67
|
||||
/* CIR Wake byte comparison tolerance */
|
||||
#define CIR_WAKE_CMP_TOLERANCE 5
|
||||
|
||||
/*
|
||||
* Extended Function Enable Registers:
|
||||
* Extended Function Index Register
|
||||
* Extended Function Data Register
|
||||
*/
|
||||
#define CR_EFIR 0x2e
|
||||
#define CR_EFDR 0x2f
|
||||
|
||||
/* Possible alternate EFER values, depends on how the chip is wired */
|
||||
#define CR_EFIR2 0x4e
|
||||
#define CR_EFDR2 0x4f
|
||||
|
||||
/* Extended Function Mode enable/disable magic values */
|
||||
#define EFER_EFM_ENABLE 0x87
|
||||
#define EFER_EFM_DISABLE 0xaa
|
||||
|
||||
/* Chip IDs found in CR_CHIP_ID_{HI,LO} */
|
||||
#define CHIP_ID_HIGH 0xb4
|
||||
#define CHIP_ID_LOW 0x72
|
||||
#define CHIP_ID_LOW2 0x73
|
||||
|
||||
/* Config regs we need to care about */
|
||||
#define CR_SOFTWARE_RESET 0x02
|
||||
#define CR_LOGICAL_DEV_SEL 0x07
|
||||
#define CR_CHIP_ID_HI 0x20
|
||||
#define CR_CHIP_ID_LO 0x21
|
||||
#define CR_DEV_POWER_DOWN 0x22 /* bit 2 is CIR power, default power on */
|
||||
#define CR_OUTPUT_PIN_SEL 0x27
|
||||
#define CR_LOGICAL_DEV_EN 0x30 /* valid for all logical devices */
|
||||
/* next three regs valid for both the CIR and CIR_WAKE logical devices */
|
||||
#define CR_CIR_BASE_ADDR_HI 0x60
|
||||
#define CR_CIR_BASE_ADDR_LO 0x61
|
||||
#define CR_CIR_IRQ_RSRC 0x70
|
||||
/* next three regs valid only for ACPI logical dev */
|
||||
#define CR_ACPI_CIR_WAKE 0xe0
|
||||
#define CR_ACPI_IRQ_EVENTS 0xf6
|
||||
#define CR_ACPI_IRQ_EVENTS2 0xf7
|
||||
|
||||
/* Logical devices that we need to care about */
|
||||
#define LOGICAL_DEV_LPT 0x01
|
||||
#define LOGICAL_DEV_CIR 0x06
|
||||
#define LOGICAL_DEV_ACPI 0x0a
|
||||
#define LOGICAL_DEV_CIR_WAKE 0x0e
|
||||
|
||||
#define LOGICAL_DEV_DISABLE 0x00
|
||||
#define LOGICAL_DEV_ENABLE 0x01
|
||||
|
||||
#define CIR_WAKE_ENABLE_BIT 0x08
|
||||
#define CIR_INTR_MOUSE_IRQ_BIT 0x80
|
||||
#define PME_INTR_CIR_PASS_BIT 0x08
|
||||
|
||||
#define OUTPUT_PIN_SEL_MASK 0xbc
|
||||
#define OUTPUT_ENABLE_CIR 0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */
|
||||
#define OUTPUT_ENABLE_CIRWB 0x40 /* enable wide-band sensor */
|
||||
|
||||
/* MCE CIR signal length, related on sample period */
|
||||
|
||||
/* MCE CIR controller signal length: about 43ms
|
||||
* 43ms / 50us (sample period) * 0.85 (inaccuracy)
|
||||
*/
|
||||
#define CONTROLLER_BUF_LEN_MIN 830
|
||||
|
||||
/* MCE CIR keyboard signal length: about 26ms
|
||||
* 26ms / 50us (sample period) * 0.85 (inaccuracy)
|
||||
*/
|
||||
#define KEYBOARD_BUF_LEN_MAX 650
|
||||
#define KEYBOARD_BUF_LEN_MIN 610
|
||||
|
||||
/* MCE CIR mouse signal length: about 24ms
|
||||
* 24ms / 50us (sample period) * 0.85 (inaccuracy)
|
||||
*/
|
||||
#define MOUSE_BUF_LEN_MIN 565
|
||||
|
||||
#define CIR_SAMPLE_PERIOD 50
|
||||
#define CIR_SAMPLE_LOW_INACCURACY 0.85
|
||||
|
||||
/* MAX silence time that driver will sent to lirc */
|
||||
#define MAX_SILENCE_TIME 60000
|
||||
|
||||
#if CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_100
|
||||
#define SAMPLE_PERIOD 100
|
||||
|
||||
#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_50
|
||||
#define SAMPLE_PERIOD 50
|
||||
|
||||
#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_25
|
||||
#define SAMPLE_PERIOD 25
|
||||
|
||||
#else
|
||||
#define SAMPLE_PERIOD 1
|
||||
#endif
|
||||
|
||||
/* as VISTA MCE definition, valid carrier value */
|
||||
#define MAX_CARRIER 60000
|
||||
#define MIN_CARRIER 30000
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
#include <linux/input.h>
|
||||
#include <media/ir-core.h>
|
||||
|
||||
#define DRIVER_VERSION "1.60"
|
||||
#define DRIVER_VERSION "1.61"
|
||||
#define DRIVER_NAME "streamzap"
|
||||
#define DRIVER_DESC "Streamzap Remote Control driver"
|
||||
|
||||
|
|
@ -61,14 +61,21 @@ static struct usb_device_id streamzap_table[] = {
|
|||
|
||||
MODULE_DEVICE_TABLE(usb, streamzap_table);
|
||||
|
||||
#define STREAMZAP_PULSE_MASK 0xf0
|
||||
#define STREAMZAP_SPACE_MASK 0x0f
|
||||
#define STREAMZAP_TIMEOUT 0xff
|
||||
#define STREAMZAP_RESOLUTION 256
|
||||
#define SZ_PULSE_MASK 0xf0
|
||||
#define SZ_SPACE_MASK 0x0f
|
||||
#define SZ_TIMEOUT 0xff
|
||||
#define SZ_RESOLUTION 256
|
||||
|
||||
/* number of samples buffered */
|
||||
#define SZ_BUF_LEN 128
|
||||
|
||||
/* from ir-rc5-sz-decoder.c */
|
||||
#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
|
||||
#define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder")
|
||||
#else
|
||||
#define load_rc5_sz_decode() 0
|
||||
#endif
|
||||
|
||||
enum StreamzapDecoderState {
|
||||
PulseSpace,
|
||||
FullPulse,
|
||||
|
|
@ -81,7 +88,6 @@ struct streamzap_ir {
|
|||
|
||||
/* ir-core */
|
||||
struct ir_dev_props *props;
|
||||
struct ir_raw_event rawir;
|
||||
|
||||
/* core device info */
|
||||
struct device *dev;
|
||||
|
|
@ -98,17 +104,6 @@ struct streamzap_ir {
|
|||
dma_addr_t dma_in;
|
||||
unsigned int buf_in_len;
|
||||
|
||||
/* timer used to support delay buffering */
|
||||
struct timer_list delay_timer;
|
||||
bool timer_running;
|
||||
spinlock_t timer_lock;
|
||||
struct timer_list flush_timer;
|
||||
bool flush;
|
||||
|
||||
/* delay buffer */
|
||||
struct kfifo fifo;
|
||||
bool fifo_initialized;
|
||||
|
||||
/* track what state we're in */
|
||||
enum StreamzapDecoderState decoder_state;
|
||||
/* tracks whether we are currently receiving some signal */
|
||||
|
|
@ -118,7 +113,7 @@ struct streamzap_ir {
|
|||
/* start time of signal; necessary for gap tracking */
|
||||
struct timeval signal_last;
|
||||
struct timeval signal_start;
|
||||
/* bool timeout_enabled; */
|
||||
bool timeout_enabled;
|
||||
|
||||
char name[128];
|
||||
char phys[64];
|
||||
|
|
@ -143,122 +138,16 @@ static struct usb_driver streamzap_driver = {
|
|||
.id_table = streamzap_table,
|
||||
};
|
||||
|
||||
static void streamzap_stop_timer(struct streamzap_ir *sz)
|
||||
static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&sz->timer_lock, flags);
|
||||
if (sz->timer_running) {
|
||||
sz->timer_running = false;
|
||||
spin_unlock_irqrestore(&sz->timer_lock, flags);
|
||||
del_timer_sync(&sz->delay_timer);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&sz->timer_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void streamzap_flush_timeout(unsigned long arg)
|
||||
{
|
||||
struct streamzap_ir *sz = (struct streamzap_ir *)arg;
|
||||
|
||||
dev_info(sz->dev, "%s: callback firing\n", __func__);
|
||||
|
||||
/* finally start accepting data */
|
||||
sz->flush = false;
|
||||
}
|
||||
|
||||
static void streamzap_delay_timeout(unsigned long arg)
|
||||
{
|
||||
struct streamzap_ir *sz = (struct streamzap_ir *)arg;
|
||||
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
|
||||
unsigned long flags;
|
||||
int len, ret;
|
||||
static unsigned long delay;
|
||||
bool wake = false;
|
||||
|
||||
/* deliver data every 10 ms */
|
||||
delay = msecs_to_jiffies(10);
|
||||
|
||||
spin_lock_irqsave(&sz->timer_lock, flags);
|
||||
|
||||
if (kfifo_len(&sz->fifo) > 0) {
|
||||
ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
|
||||
if (ret != sizeof(rawir))
|
||||
dev_err(sz->dev, "Problem w/kfifo_out...\n");
|
||||
ir_raw_event_store(sz->idev, &rawir);
|
||||
wake = true;
|
||||
}
|
||||
|
||||
len = kfifo_len(&sz->fifo);
|
||||
if (len > 0) {
|
||||
while ((len < SZ_BUF_LEN / 2) &&
|
||||
(len < SZ_BUF_LEN * sizeof(int))) {
|
||||
ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
|
||||
if (ret != sizeof(rawir))
|
||||
dev_err(sz->dev, "Problem w/kfifo_out...\n");
|
||||
ir_raw_event_store(sz->idev, &rawir);
|
||||
wake = true;
|
||||
len = kfifo_len(&sz->fifo);
|
||||
}
|
||||
if (sz->timer_running)
|
||||
mod_timer(&sz->delay_timer, jiffies + delay);
|
||||
|
||||
} else {
|
||||
sz->timer_running = false;
|
||||
}
|
||||
|
||||
if (wake)
|
||||
ir_raw_event_handle(sz->idev);
|
||||
|
||||
spin_unlock_irqrestore(&sz->timer_lock, flags);
|
||||
}
|
||||
|
||||
static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
|
||||
{
|
||||
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
|
||||
bool wake = false;
|
||||
int ret;
|
||||
|
||||
while (kfifo_len(&sz->fifo) > 0) {
|
||||
ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
|
||||
if (ret != sizeof(rawir))
|
||||
dev_err(sz->dev, "Problem w/kfifo_out...\n");
|
||||
ir_raw_event_store(sz->idev, &rawir);
|
||||
wake = true;
|
||||
}
|
||||
|
||||
if (wake)
|
||||
ir_raw_event_handle(sz->idev);
|
||||
}
|
||||
|
||||
static void sz_push(struct streamzap_ir *sz)
|
||||
{
|
||||
struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&sz->timer_lock, flags);
|
||||
if (kfifo_len(&sz->fifo) >= sizeof(int) * SZ_BUF_LEN) {
|
||||
ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
|
||||
if (ret != sizeof(rawir))
|
||||
dev_err(sz->dev, "Problem w/kfifo_out...\n");
|
||||
ir_raw_event_store(sz->idev, &rawir);
|
||||
}
|
||||
|
||||
kfifo_in(&sz->fifo, &sz->rawir, sizeof(rawir));
|
||||
|
||||
if (!sz->timer_running) {
|
||||
sz->delay_timer.expires = jiffies + (HZ / 10);
|
||||
add_timer(&sz->delay_timer);
|
||||
sz->timer_running = true;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&sz->timer_lock, flags);
|
||||
ir_raw_event_store(sz->idev, &rawir);
|
||||
}
|
||||
|
||||
static void sz_push_full_pulse(struct streamzap_ir *sz,
|
||||
unsigned char value)
|
||||
{
|
||||
DEFINE_IR_RAW_EVENT(rawir);
|
||||
|
||||
if (sz->idle) {
|
||||
long deltv;
|
||||
|
||||
|
|
@ -266,57 +155,59 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
|
|||
do_gettimeofday(&sz->signal_start);
|
||||
|
||||
deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec;
|
||||
sz->rawir.pulse = false;
|
||||
rawir.pulse = false;
|
||||
if (deltv > 15) {
|
||||
/* really long time */
|
||||
sz->rawir.duration = IR_MAX_DURATION;
|
||||
rawir.duration = IR_MAX_DURATION;
|
||||
} else {
|
||||
sz->rawir.duration = (int)(deltv * 1000000 +
|
||||
rawir.duration = (int)(deltv * 1000000 +
|
||||
sz->signal_start.tv_usec -
|
||||
sz->signal_last.tv_usec);
|
||||
sz->rawir.duration -= sz->sum;
|
||||
sz->rawir.duration *= 1000;
|
||||
sz->rawir.duration &= IR_MAX_DURATION;
|
||||
rawir.duration -= sz->sum;
|
||||
rawir.duration *= 1000;
|
||||
rawir.duration &= IR_MAX_DURATION;
|
||||
}
|
||||
dev_dbg(sz->dev, "ls %u\n", sz->rawir.duration);
|
||||
sz_push(sz);
|
||||
dev_dbg(sz->dev, "ls %u\n", rawir.duration);
|
||||
sz_push(sz, rawir);
|
||||
|
||||
sz->idle = 0;
|
||||
sz->idle = false;
|
||||
sz->sum = 0;
|
||||
}
|
||||
|
||||
sz->rawir.pulse = true;
|
||||
sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
|
||||
sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
|
||||
sz->sum += sz->rawir.duration;
|
||||
sz->rawir.duration *= 1000;
|
||||
sz->rawir.duration &= IR_MAX_DURATION;
|
||||
dev_dbg(sz->dev, "p %u\n", sz->rawir.duration);
|
||||
sz_push(sz);
|
||||
rawir.pulse = true;
|
||||
rawir.duration = ((int) value) * SZ_RESOLUTION;
|
||||
rawir.duration += SZ_RESOLUTION / 2;
|
||||
sz->sum += rawir.duration;
|
||||
rawir.duration *= 1000;
|
||||
rawir.duration &= IR_MAX_DURATION;
|
||||
dev_dbg(sz->dev, "p %u\n", rawir.duration);
|
||||
sz_push(sz, rawir);
|
||||
}
|
||||
|
||||
static void sz_push_half_pulse(struct streamzap_ir *sz,
|
||||
unsigned char value)
|
||||
{
|
||||
sz_push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK) >> 4);
|
||||
sz_push_full_pulse(sz, (value & SZ_PULSE_MASK) >> 4);
|
||||
}
|
||||
|
||||
static void sz_push_full_space(struct streamzap_ir *sz,
|
||||
unsigned char value)
|
||||
{
|
||||
sz->rawir.pulse = false;
|
||||
sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
|
||||
sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
|
||||
sz->sum += sz->rawir.duration;
|
||||
sz->rawir.duration *= 1000;
|
||||
dev_dbg(sz->dev, "s %u\n", sz->rawir.duration);
|
||||
sz_push(sz);
|
||||
DEFINE_IR_RAW_EVENT(rawir);
|
||||
|
||||
rawir.pulse = false;
|
||||
rawir.duration = ((int) value) * SZ_RESOLUTION;
|
||||
rawir.duration += SZ_RESOLUTION / 2;
|
||||
sz->sum += rawir.duration;
|
||||
rawir.duration *= 1000;
|
||||
dev_dbg(sz->dev, "s %u\n", rawir.duration);
|
||||
sz_push(sz, rawir);
|
||||
}
|
||||
|
||||
static void sz_push_half_space(struct streamzap_ir *sz,
|
||||
unsigned long value)
|
||||
{
|
||||
sz_push_full_space(sz, value & STREAMZAP_SPACE_MASK);
|
||||
sz_push_full_space(sz, value & SZ_SPACE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -330,10 +221,8 @@ static void streamzap_callback(struct urb *urb)
|
|||
struct streamzap_ir *sz;
|
||||
unsigned int i;
|
||||
int len;
|
||||
#if 0
|
||||
static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) &
|
||||
static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
|
||||
IR_MAX_DURATION) | 0x03000000);
|
||||
#endif
|
||||
|
||||
if (!urb)
|
||||
return;
|
||||
|
|
@ -356,57 +245,53 @@ static void streamzap_callback(struct urb *urb)
|
|||
}
|
||||
|
||||
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
|
||||
if (!sz->flush) {
|
||||
for (i = 0; i < urb->actual_length; i++) {
|
||||
dev_dbg(sz->dev, "%d: %x\n", i,
|
||||
(unsigned char)sz->buf_in[i]);
|
||||
switch (sz->decoder_state) {
|
||||
case PulseSpace:
|
||||
if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
|
||||
STREAMZAP_PULSE_MASK) {
|
||||
sz->decoder_state = FullPulse;
|
||||
continue;
|
||||
} else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
|
||||
== STREAMZAP_SPACE_MASK) {
|
||||
sz_push_half_pulse(sz, sz->buf_in[i]);
|
||||
sz->decoder_state = FullSpace;
|
||||
continue;
|
||||
} else {
|
||||
sz_push_half_pulse(sz, sz->buf_in[i]);
|
||||
sz_push_half_space(sz, sz->buf_in[i]);
|
||||
}
|
||||
break;
|
||||
case FullPulse:
|
||||
sz_push_full_pulse(sz, sz->buf_in[i]);
|
||||
sz->decoder_state = IgnorePulse;
|
||||
break;
|
||||
case FullSpace:
|
||||
if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
|
||||
sz->idle = 1;
|
||||
streamzap_stop_timer(sz);
|
||||
#if 0
|
||||
if (sz->timeout_enabled) {
|
||||
sz->rawir.pulse = false;
|
||||
sz->rawir.duration = timeout;
|
||||
sz->rawir.duration *= 1000;
|
||||
sz_push(sz);
|
||||
}
|
||||
#endif
|
||||
streamzap_flush_delay_buffer(sz);
|
||||
} else
|
||||
sz_push_full_space(sz, sz->buf_in[i]);
|
||||
sz->decoder_state = PulseSpace;
|
||||
break;
|
||||
case IgnorePulse:
|
||||
if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) ==
|
||||
STREAMZAP_SPACE_MASK) {
|
||||
sz->decoder_state = FullSpace;
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
dev_dbg(sz->dev, "sz idx %d: %x\n",
|
||||
i, (unsigned char)sz->buf_in[i]);
|
||||
switch (sz->decoder_state) {
|
||||
case PulseSpace:
|
||||
if ((sz->buf_in[i] & SZ_PULSE_MASK) ==
|
||||
SZ_PULSE_MASK) {
|
||||
sz->decoder_state = FullPulse;
|
||||
continue;
|
||||
} else if ((sz->buf_in[i] & SZ_SPACE_MASK)
|
||||
== SZ_SPACE_MASK) {
|
||||
sz_push_half_pulse(sz, sz->buf_in[i]);
|
||||
sz->decoder_state = FullSpace;
|
||||
continue;
|
||||
} else {
|
||||
sz_push_half_pulse(sz, sz->buf_in[i]);
|
||||
sz_push_half_space(sz, sz->buf_in[i]);
|
||||
sz->decoder_state = PulseSpace;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FullPulse:
|
||||
sz_push_full_pulse(sz, sz->buf_in[i]);
|
||||
sz->decoder_state = IgnorePulse;
|
||||
break;
|
||||
case FullSpace:
|
||||
if (sz->buf_in[i] == SZ_TIMEOUT) {
|
||||
DEFINE_IR_RAW_EVENT(rawir);
|
||||
|
||||
rawir.pulse = false;
|
||||
rawir.duration = timeout;
|
||||
sz->idle = true;
|
||||
if (sz->timeout_enabled)
|
||||
sz_push(sz, rawir);
|
||||
ir_raw_event_handle(sz->idev);
|
||||
} else {
|
||||
sz_push_full_space(sz, sz->buf_in[i]);
|
||||
}
|
||||
sz->decoder_state = PulseSpace;
|
||||
break;
|
||||
case IgnorePulse:
|
||||
if ((sz->buf_in[i] & SZ_SPACE_MASK) ==
|
||||
SZ_SPACE_MASK) {
|
||||
sz->decoder_state = FullSpace;
|
||||
continue;
|
||||
}
|
||||
sz_push_half_space(sz, sz->buf_in[i]);
|
||||
sz->decoder_state = PulseSpace;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -446,12 +331,11 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
|
|||
|
||||
props->priv = sz;
|
||||
props->driver_type = RC_DRIVER_IR_RAW;
|
||||
/* FIXME: not sure about supported protocols, check on this */
|
||||
props->allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6;
|
||||
props->allowed_protos = IR_TYPE_ALL;
|
||||
|
||||
sz->props = props;
|
||||
|
||||
ret = ir_input_register(idev, RC_MAP_RC5_STREAMZAP, props, DRIVER_NAME);
|
||||
ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "remote input device register failed\n");
|
||||
goto irdev_failed;
|
||||
|
|
@ -467,29 +351,6 @@ idev_alloc_failed:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int streamzap_delay_buf_init(struct streamzap_ir *sz)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = kfifo_alloc(&sz->fifo, sizeof(int) * SZ_BUF_LEN,
|
||||
GFP_KERNEL);
|
||||
if (ret == 0)
|
||||
sz->fifo_initialized = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void streamzap_start_flush_timer(struct streamzap_ir *sz)
|
||||
{
|
||||
sz->flush_timer.expires = jiffies + HZ;
|
||||
sz->flush = true;
|
||||
add_timer(&sz->flush_timer);
|
||||
|
||||
sz->urb_in->dev = sz->usbdev;
|
||||
if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
|
||||
dev_err(sz->dev, "urb submit failed\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* streamzap_probe
|
||||
*
|
||||
|
|
@ -575,35 +436,21 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
|
|||
snprintf(name + strlen(name), sizeof(name) - strlen(name),
|
||||
" %s", buf);
|
||||
|
||||
retval = streamzap_delay_buf_init(sz);
|
||||
if (retval) {
|
||||
dev_err(&intf->dev, "%s: delay buffer init failed\n", __func__);
|
||||
goto free_urb_in;
|
||||
}
|
||||
|
||||
sz->idev = streamzap_init_input_dev(sz);
|
||||
if (!sz->idev)
|
||||
goto input_dev_fail;
|
||||
|
||||
sz->idle = true;
|
||||
sz->decoder_state = PulseSpace;
|
||||
/* FIXME: don't yet have a way to set this */
|
||||
sz->timeout_enabled = true;
|
||||
#if 0
|
||||
/* not yet supported, depends on patches from maxim */
|
||||
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
|
||||
sz->timeout_enabled = false;
|
||||
sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
|
||||
sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
|
||||
sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
|
||||
sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
|
||||
#endif
|
||||
|
||||
init_timer(&sz->delay_timer);
|
||||
sz->delay_timer.function = streamzap_delay_timeout;
|
||||
sz->delay_timer.data = (unsigned long)sz;
|
||||
spin_lock_init(&sz->timer_lock);
|
||||
|
||||
init_timer(&sz->flush_timer);
|
||||
sz->flush_timer.function = streamzap_flush_timeout;
|
||||
sz->flush_timer.data = (unsigned long)sz;
|
||||
|
||||
do_gettimeofday(&sz->signal_start);
|
||||
|
||||
/* Complete final initialisations */
|
||||
|
|
@ -615,16 +462,18 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
|
|||
|
||||
usb_set_intfdata(intf, sz);
|
||||
|
||||
streamzap_start_flush_timer(sz);
|
||||
if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
|
||||
dev_err(sz->dev, "urb submit failed\n");
|
||||
|
||||
dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
|
||||
usbdev->bus->busnum, usbdev->devnum);
|
||||
|
||||
/* Load the streamzap not-quite-rc5 decoder too */
|
||||
load_rc5_sz_decode();
|
||||
|
||||
return 0;
|
||||
|
||||
input_dev_fail:
|
||||
kfifo_free(&sz->fifo);
|
||||
free_urb_in:
|
||||
usb_free_urb(sz->urb_in);
|
||||
free_buf_in:
|
||||
usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
|
||||
|
|
@ -654,13 +503,6 @@ static void streamzap_disconnect(struct usb_interface *interface)
|
|||
if (!sz)
|
||||
return;
|
||||
|
||||
if (sz->flush) {
|
||||
sz->flush = false;
|
||||
del_timer_sync(&sz->flush_timer);
|
||||
}
|
||||
|
||||
streamzap_stop_timer(sz);
|
||||
|
||||
sz->usbdev = NULL;
|
||||
ir_input_unregister(sz->idev);
|
||||
usb_kill_urb(sz->urb_in);
|
||||
|
|
@ -674,13 +516,6 @@ static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
|
|||
{
|
||||
struct streamzap_ir *sz = usb_get_intfdata(intf);
|
||||
|
||||
if (sz->flush) {
|
||||
sz->flush = false;
|
||||
del_timer_sync(&sz->flush_timer);
|
||||
}
|
||||
|
||||
streamzap_stop_timer(sz);
|
||||
|
||||
usb_kill_urb(sz->urb_in);
|
||||
|
||||
return 0;
|
||||
|
|
@ -690,13 +525,6 @@ static int streamzap_resume(struct usb_interface *intf)
|
|||
{
|
||||
struct streamzap_ir *sz = usb_get_intfdata(intf);
|
||||
|
||||
if (sz->fifo_initialized)
|
||||
kfifo_reset(&sz->fifo);
|
||||
|
||||
sz->flush_timer.expires = jiffies + HZ;
|
||||
sz->flush = true;
|
||||
add_timer(&sz->flush_timer);
|
||||
|
||||
if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
|
||||
dev_err(sz->dev, "Error sumbiting urb\n");
|
||||
return -EIO;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
|
|||
|
||||
BUG_ON(in_interrupt());
|
||||
|
||||
videobuf_waiton(&buf->vb,0,0);
|
||||
videobuf_waiton(q, &buf->vb, 0, 0);
|
||||
videobuf_dma_unmap(q->dev, dma);
|
||||
videobuf_dma_free(dma);
|
||||
buf->vb.state = VIDEOBUF_NEEDS_INIT;
|
||||
|
|
|
|||
|
|
@ -414,7 +414,6 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c
|
|||
i2c_adapter->dev.parent = &dev->pci->dev;
|
||||
i2c_adapter->algo = &saa7146_algo;
|
||||
i2c_adapter->algo_data = NULL;
|
||||
i2c_adapter->id = I2C_HW_SAA7146;
|
||||
i2c_adapter->timeout = SAA7146_I2C_TIMEOUT;
|
||||
i2c_adapter->retries = SAA7146_I2C_RETRIES;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
|
|||
V4L2_BUF_TYPE_VBI_CAPTURE,
|
||||
V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
|
||||
sizeof(struct saa7146_buf),
|
||||
file);
|
||||
file, NULL);
|
||||
|
||||
init_timer(&fh->vbi_read_timeout);
|
||||
fh->vbi_read_timeout.function = vbi_read_timeout;
|
||||
|
|
|
|||
|
|
@ -1386,7 +1386,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
|
|||
V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
V4L2_FIELD_INTERLACED,
|
||||
sizeof(struct saa7146_buf),
|
||||
file);
|
||||
file, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,4 +179,11 @@ config MEDIA_TUNER_MAX2165
|
|||
help
|
||||
A driver for the silicon tuner MAX2165 from Maxim.
|
||||
|
||||
config MEDIA_TUNER_TDA18218
|
||||
tristate "NXP TDA18218 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
NXP TDA18218 silicon tuner driver.
|
||||
|
||||
endif # MEDIA_TUNER_CUSTOMISE
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
|
|||
obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
|
||||
|
|
|
|||
334
drivers/media/common/tuners/tda18218.c
Normal file
334
drivers/media/common/tuners/tda18218.c
Normal file
|
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
* NXP TDA18218HN silicon tuner driver
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "tda18218.h"
|
||||
#include "tda18218_priv.h"
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
|
||||
|
||||
/* write multiple registers */
|
||||
static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[1+len], quotient, remainder, i, msg_len, msg_len_max;
|
||||
struct i2c_msg msg[1] = {
|
||||
{
|
||||
.addr = priv->cfg->i2c_address,
|
||||
.flags = 0,
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
msg_len_max = priv->cfg->i2c_wr_max - 1;
|
||||
quotient = len / msg_len_max;
|
||||
remainder = len % msg_len_max;
|
||||
msg_len = msg_len_max;
|
||||
for (i = 0; (i <= quotient && remainder); i++) {
|
||||
if (i == quotient) /* set len of the last msg */
|
||||
msg_len = remainder;
|
||||
|
||||
msg[0].len = msg_len + 1;
|
||||
buf[0] = reg + i * msg_len_max;
|
||||
memcpy(&buf[1], &val[i * msg_len_max], msg_len);
|
||||
|
||||
ret = i2c_transfer(priv->i2c, msg, 1);
|
||||
if (ret != 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* read multiple registers */
|
||||
static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[reg+len]; /* we must start read always from reg 0x00 */
|
||||
struct i2c_msg msg[2] = {
|
||||
{
|
||||
.addr = priv->cfg->i2c_address,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = "\x00",
|
||||
}, {
|
||||
.addr = priv->cfg->i2c_address,
|
||||
.flags = I2C_M_RD,
|
||||
.len = sizeof(buf),
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(priv->i2c, msg, 2);
|
||||
if (ret == 2) {
|
||||
memcpy(val, &buf[reg], len);
|
||||
ret = 0;
|
||||
} else {
|
||||
warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* write single register */
|
||||
static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
|
||||
{
|
||||
return tda18218_wr_regs(priv, reg, &val, 1);
|
||||
}
|
||||
|
||||
/* read single register */
|
||||
|
||||
static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
|
||||
{
|
||||
return tda18218_rd_regs(priv, reg, val, 1);
|
||||
}
|
||||
|
||||
static int tda18218_set_params(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *params)
|
||||
{
|
||||
struct tda18218_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
u8 buf[3], i, BP_Filter, LP_Fc;
|
||||
u32 LO_Frac;
|
||||
/* TODO: find out correct AGC algorithm */
|
||||
u8 agc[][2] = {
|
||||
{ R20_AGC11, 0x60 },
|
||||
{ R23_AGC21, 0x02 },
|
||||
{ R20_AGC11, 0xa0 },
|
||||
{ R23_AGC21, 0x09 },
|
||||
{ R20_AGC11, 0xe0 },
|
||||
{ R23_AGC21, 0x0c },
|
||||
{ R20_AGC11, 0x40 },
|
||||
{ R23_AGC21, 0x01 },
|
||||
{ R20_AGC11, 0x80 },
|
||||
{ R23_AGC21, 0x08 },
|
||||
{ R20_AGC11, 0xc0 },
|
||||
{ R23_AGC21, 0x0b },
|
||||
{ R24_AGC22, 0x1c },
|
||||
{ R24_AGC22, 0x0c },
|
||||
};
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
/* low-pass filter cut-off frequency */
|
||||
switch (params->u.ofdm.bandwidth) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
LP_Fc = 0;
|
||||
LO_Frac = params->frequency + 4000000;
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
LP_Fc = 1;
|
||||
LO_Frac = params->frequency + 3500000;
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
default:
|
||||
LP_Fc = 2;
|
||||
LO_Frac = params->frequency + 4000000;
|
||||
break;
|
||||
}
|
||||
|
||||
/* band-pass filter */
|
||||
if (LO_Frac < 188000000)
|
||||
BP_Filter = 3;
|
||||
else if (LO_Frac < 253000000)
|
||||
BP_Filter = 4;
|
||||
else if (LO_Frac < 343000000)
|
||||
BP_Filter = 5;
|
||||
else
|
||||
BP_Filter = 6;
|
||||
|
||||
buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
|
||||
buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
|
||||
buf[2] = priv->regs[R1C_AGC2B];
|
||||
ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
|
||||
buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
|
||||
buf[2] = (LO_Frac / 1000) << 4 |
|
||||
(priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
|
||||
ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
|
||||
ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
|
||||
ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
/* trigger AGC */
|
||||
for (i = 0; i < ARRAY_SIZE(agc); i++) {
|
||||
ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
|
||||
if (ret)
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
if (ret)
|
||||
dbg("%s: failed ret:%d", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tda18218_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tda18218_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
/* standby */
|
||||
ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
if (ret)
|
||||
dbg("%s: failed ret:%d", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tda18218_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tda18218_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
|
||||
/* TODO: calibrations */
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
if (ret)
|
||||
dbg("%s: failed ret:%d", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tda18218_release(struct dvb_frontend *fe)
|
||||
{
|
||||
kfree(fe->tuner_priv);
|
||||
fe->tuner_priv = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dvb_tuner_ops tda18218_tuner_ops = {
|
||||
.info = {
|
||||
.name = "NXP TDA18218",
|
||||
|
||||
.frequency_min = 174000000,
|
||||
.frequency_max = 864000000,
|
||||
.frequency_step = 1000,
|
||||
},
|
||||
|
||||
.release = tda18218_release,
|
||||
.init = tda18218_init,
|
||||
.sleep = tda18218_sleep,
|
||||
|
||||
.set_params = tda18218_set_params,
|
||||
};
|
||||
|
||||
struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, struct tda18218_config *cfg)
|
||||
{
|
||||
struct tda18218_priv *priv = NULL;
|
||||
u8 val;
|
||||
int ret;
|
||||
/* chip default registers values */
|
||||
static u8 def_regs[] = {
|
||||
0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
|
||||
0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
|
||||
0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
|
||||
0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
|
||||
0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
|
||||
0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
|
||||
};
|
||||
|
||||
priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
return NULL;
|
||||
|
||||
priv->cfg = cfg;
|
||||
priv->i2c = i2c;
|
||||
fe->tuner_priv = priv;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
/* check if the tuner is there */
|
||||
ret = tda18218_rd_reg(priv, R00_ID, &val);
|
||||
dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
|
||||
if (ret || val != def_regs[R00_ID]) {
|
||||
kfree(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info("NXP TDA18218HN successfully identified.");
|
||||
|
||||
memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
|
||||
sizeof(struct dvb_tuner_ops));
|
||||
memcpy(priv->regs, def_regs, sizeof(def_regs));
|
||||
|
||||
/* loop-through enabled chip default register values */
|
||||
if (priv->cfg->loop_through) {
|
||||
priv->regs[R17_PD1] = 0xb0;
|
||||
priv->regs[R18_PD2] = 0x59;
|
||||
}
|
||||
|
||||
/* standby */
|
||||
ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
|
||||
if (ret)
|
||||
dbg("%s: failed ret:%d", __func__, ret);
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(tda18218_attach);
|
||||
|
||||
MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
MODULE_LICENSE("GPL");
|
||||
45
drivers/media/common/tuners/tda18218.h
Normal file
45
drivers/media/common/tuners/tda18218.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* NXP TDA18218HN silicon tuner driver
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef TDA18218_H
|
||||
#define TDA18218_H
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
struct tda18218_config {
|
||||
u8 i2c_address;
|
||||
u8 i2c_wr_max;
|
||||
u8 loop_through:1;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_MEDIA_TUNER_TDA18218) || \
|
||||
(defined(CONFIG_MEDIA_TUNER_TDA18218_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, struct tda18218_config *cfg);
|
||||
#else
|
||||
static inline struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, struct tda18218_config *cfg)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
106
drivers/media/common/tuners/tda18218_priv.h
Normal file
106
drivers/media/common/tuners/tda18218_priv.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* NXP TDA18218HN silicon tuner driver
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef TDA18218_PRIV_H
|
||||
#define TDA18218_PRIV_H
|
||||
|
||||
#define LOG_PREFIX "tda18218"
|
||||
|
||||
#undef dbg
|
||||
#define dbg(f, arg...) \
|
||||
if (debug) \
|
||||
printk(KERN_DEBUG LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef err
|
||||
#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef info
|
||||
#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef warn
|
||||
#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
|
||||
|
||||
#define R00_ID 0x00 /* ID byte */
|
||||
#define R01_R1 0x01 /* Read byte 1 */
|
||||
#define R02_R2 0x02 /* Read byte 2 */
|
||||
#define R03_R3 0x03 /* Read byte 3 */
|
||||
#define R04_R4 0x04 /* Read byte 4 */
|
||||
#define R05_R5 0x05 /* Read byte 5 */
|
||||
#define R06_R6 0x06 /* Read byte 6 */
|
||||
#define R07_MD1 0x07 /* Main divider byte 1 */
|
||||
#define R08_PSM1 0x08 /* PSM byte 1 */
|
||||
#define R09_MD2 0x09 /* Main divider byte 2 */
|
||||
#define R0A_MD3 0x0a /* Main divider byte 1 */
|
||||
#define R0B_MD4 0x0b /* Main divider byte 4 */
|
||||
#define R0C_MD5 0x0c /* Main divider byte 5 */
|
||||
#define R0D_MD6 0x0d /* Main divider byte 6 */
|
||||
#define R0E_MD7 0x0e /* Main divider byte 7 */
|
||||
#define R0F_MD8 0x0f /* Main divider byte 8 */
|
||||
#define R10_CD1 0x10 /* Call divider byte 1 */
|
||||
#define R11_CD2 0x11 /* Call divider byte 2 */
|
||||
#define R12_CD3 0x12 /* Call divider byte 3 */
|
||||
#define R13_CD4 0x13 /* Call divider byte 4 */
|
||||
#define R14_CD5 0x14 /* Call divider byte 5 */
|
||||
#define R15_CD6 0x15 /* Call divider byte 6 */
|
||||
#define R16_CD7 0x16 /* Call divider byte 7 */
|
||||
#define R17_PD1 0x17 /* Power-down byte 1 */
|
||||
#define R18_PD2 0x18 /* Power-down byte 2 */
|
||||
#define R19_XTOUT 0x19 /* XTOUT byte */
|
||||
#define R1A_IF1 0x1a /* IF byte 1 */
|
||||
#define R1B_IF2 0x1b /* IF byte 2 */
|
||||
#define R1C_AGC2B 0x1c /* AGC2b byte */
|
||||
#define R1D_PSM2 0x1d /* PSM byte 2 */
|
||||
#define R1E_PSM3 0x1e /* PSM byte 3 */
|
||||
#define R1F_PSM4 0x1f /* PSM byte 4 */
|
||||
#define R20_AGC11 0x20 /* AGC1 byte 1 */
|
||||
#define R21_AGC12 0x21 /* AGC1 byte 2 */
|
||||
#define R22_AGC13 0x22 /* AGC1 byte 3 */
|
||||
#define R23_AGC21 0x23 /* AGC2 byte 1 */
|
||||
#define R24_AGC22 0x24 /* AGC2 byte 2 */
|
||||
#define R25_AAGC 0x25 /* Analog AGC byte */
|
||||
#define R26_RC 0x26 /* RC byte */
|
||||
#define R27_RSSI 0x27 /* RSSI byte */
|
||||
#define R28_IRCAL1 0x28 /* IR CAL byte 1 */
|
||||
#define R29_IRCAL2 0x29 /* IR CAL byte 2 */
|
||||
#define R2A_IRCAL3 0x2a /* IR CAL byte 3 */
|
||||
#define R2B_IRCAL4 0x2b /* IR CAL byte 4 */
|
||||
#define R2C_RFCAL1 0x2c /* RF CAL byte 1 */
|
||||
#define R2D_RFCAL2 0x2d /* RF CAL byte 2 */
|
||||
#define R2E_RFCAL3 0x2e /* RF CAL byte 3 */
|
||||
#define R2F_RFCAL4 0x2f /* RF CAL byte 4 */
|
||||
#define R30_RFCAL5 0x30 /* RF CAL byte 5 */
|
||||
#define R31_RFCAL6 0x31 /* RF CAL byte 6 */
|
||||
#define R32_RFCAL7 0x32 /* RF CAL byte 7 */
|
||||
#define R33_RFCAL8 0x33 /* RF CAL byte 8 */
|
||||
#define R34_RFCAL9 0x34 /* RF CAL byte 9 */
|
||||
#define R35_RFCAL10 0x35 /* RF CAL byte 10 */
|
||||
#define R36_RFCALRAM1 0x36 /* RF CAL RAM byte 1 */
|
||||
#define R37_RFCALRAM2 0x37 /* RF CAL RAM byte 2 */
|
||||
#define R38_MARGIN 0x38 /* Margin byte */
|
||||
#define R39_FMAX1 0x39 /* Fmax byte 1 */
|
||||
#define R3A_FMAX2 0x3a /* Fmax byte 2 */
|
||||
|
||||
#define TDA18218_NUM_REGS 59
|
||||
|
||||
struct tda18218_priv {
|
||||
struct tda18218_config *cfg;
|
||||
struct i2c_adapter *i2c;
|
||||
|
||||
u8 regs[TDA18218_NUM_REGS];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -193,25 +193,51 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
|
|||
unsigned char *regs = priv->tda18271_regs;
|
||||
unsigned char buf[TDA18271_NUM_REGS + 1];
|
||||
struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0,
|
||||
.buf = buf, .len = len + 1 };
|
||||
int i, ret;
|
||||
.buf = buf };
|
||||
int i, ret = 1, max;
|
||||
|
||||
BUG_ON((len == 0) || (idx + len > sizeof(buf)));
|
||||
|
||||
buf[0] = idx;
|
||||
for (i = 1; i <= len; i++)
|
||||
buf[i] = regs[idx - 1 + i];
|
||||
|
||||
switch (priv->small_i2c) {
|
||||
case TDA18271_03_BYTE_CHUNK_INIT:
|
||||
max = 3;
|
||||
break;
|
||||
case TDA18271_08_BYTE_CHUNK_INIT:
|
||||
max = 8;
|
||||
break;
|
||||
case TDA18271_16_BYTE_CHUNK_INIT:
|
||||
max = 16;
|
||||
break;
|
||||
case TDA18271_39_BYTE_CHUNK_INIT:
|
||||
default:
|
||||
max = 39;
|
||||
}
|
||||
|
||||
tda18271_i2c_gate_ctrl(fe, 1);
|
||||
while (len) {
|
||||
if (max > len)
|
||||
max = len;
|
||||
|
||||
/* write registers */
|
||||
ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
|
||||
buf[0] = idx;
|
||||
for (i = 1; i <= max; i++)
|
||||
buf[i] = regs[idx - 1 + i];
|
||||
|
||||
msg.len = max + 1;
|
||||
|
||||
/* write registers */
|
||||
ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
|
||||
if (ret != 1)
|
||||
break;
|
||||
|
||||
idx += max;
|
||||
len -= max;
|
||||
}
|
||||
tda18271_i2c_gate_ctrl(fe, 0);
|
||||
|
||||
if (ret != 1)
|
||||
tda_err("ERROR: idx = 0x%x, len = %d, "
|
||||
"i2c_transfer returned: %d\n", idx, len, ret);
|
||||
"i2c_transfer returned: %d\n", idx, max, ret);
|
||||
|
||||
return (ret == 1 ? 0 : ret);
|
||||
}
|
||||
|
|
@ -326,24 +352,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
|
|||
regs[R_EB22] = 0x48;
|
||||
regs[R_EB23] = 0xb0;
|
||||
|
||||
switch (priv->small_i2c) {
|
||||
case TDA18271_08_BYTE_CHUNK_INIT:
|
||||
tda18271_write_regs(fe, 0x00, 0x08);
|
||||
tda18271_write_regs(fe, 0x08, 0x08);
|
||||
tda18271_write_regs(fe, 0x10, 0x08);
|
||||
tda18271_write_regs(fe, 0x18, 0x08);
|
||||
tda18271_write_regs(fe, 0x20, 0x07);
|
||||
break;
|
||||
case TDA18271_16_BYTE_CHUNK_INIT:
|
||||
tda18271_write_regs(fe, 0x00, 0x10);
|
||||
tda18271_write_regs(fe, 0x10, 0x10);
|
||||
tda18271_write_regs(fe, 0x20, 0x07);
|
||||
break;
|
||||
case TDA18271_39_BYTE_CHUNK_INIT:
|
||||
default:
|
||||
tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
|
||||
break;
|
||||
}
|
||||
tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
|
||||
|
||||
/* setup agc1 gain */
|
||||
regs[R_EB17] = 0x00;
|
||||
|
|
|
|||
|
|
@ -1156,7 +1156,6 @@ static int tda18271_get_id(struct dvb_frontend *fe)
|
|||
struct tda18271_priv *priv = fe->tuner_priv;
|
||||
unsigned char *regs = priv->tda18271_regs;
|
||||
char *name;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
tda18271_read_regs(fe);
|
||||
|
|
@ -1172,17 +1171,16 @@ static int tda18271_get_id(struct dvb_frontend *fe)
|
|||
priv->id = TDA18271HDC2;
|
||||
break;
|
||||
default:
|
||||
name = "Unknown device";
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
tda_info("Unknown device (%i) detected @ %d-%04x, device not supported.\n",
|
||||
regs[R_ID], i2c_adapter_id(priv->i2c_props.adap),
|
||||
priv->i2c_props.addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tda_info("%s detected @ %d-%04x%s\n", name,
|
||||
i2c_adapter_id(priv->i2c_props.adap),
|
||||
priv->i2c_props.addr,
|
||||
(0 == ret) ? "" : ", device not supported.");
|
||||
tda_info("%s detected @ %d-%04x\n", name,
|
||||
i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tda18271_setup_configuration(struct dvb_frontend *fe,
|
||||
|
|
|
|||
|
|
@ -80,8 +80,9 @@ enum tda18271_output_options {
|
|||
|
||||
enum tda18271_small_i2c {
|
||||
TDA18271_39_BYTE_CHUNK_INIT = 0,
|
||||
TDA18271_16_BYTE_CHUNK_INIT = 1,
|
||||
TDA18271_08_BYTE_CHUNK_INIT = 2,
|
||||
TDA18271_16_BYTE_CHUNK_INIT = 16,
|
||||
TDA18271_08_BYTE_CHUNK_INIT = 8,
|
||||
TDA18271_03_BYTE_CHUNK_INIT = 3,
|
||||
};
|
||||
|
||||
struct tda18271_config {
|
||||
|
|
|
|||
|
|
@ -1042,7 +1042,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
|
|||
|
||||
struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
struct xc5000_config *cfg)
|
||||
const struct xc5000_config *cfg)
|
||||
{
|
||||
struct xc5000_priv *priv = NULL;
|
||||
int instance;
|
||||
|
|
|
|||
|
|
@ -53,11 +53,11 @@ struct xc5000_config {
|
|||
(defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
struct xc5000_config *cfg);
|
||||
const struct xc5000_config *cfg);
|
||||
#else
|
||||
static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
struct xc5000_config *cfg)
|
||||
const struct xc5000_config *cfg)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -245,9 +245,6 @@ int flexcop_i2c_init(struct flexcop_device *fc)
|
|||
i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
|
||||
i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]);
|
||||
|
||||
fc->fc_i2c_adap[0].i2c_adap.class =
|
||||
fc->fc_i2c_adap[1].i2c_adap.class =
|
||||
fc->fc_i2c_adap[2].i2c_adap.class = I2C_CLASS_TV_DIGITAL;
|
||||
fc->fc_i2c_adap[0].i2c_adap.algo =
|
||||
fc->fc_i2c_adap[1].i2c_adap.algo =
|
||||
fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo;
|
||||
|
|
|
|||
|
|
@ -862,7 +862,6 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
|
|||
i2c_set_adapdata(&dev->i2c_adap, dev);
|
||||
strcpy(dev->i2c_adap.name, DRIVER_NAME);
|
||||
dev->i2c_adap.owner = THIS_MODULE;
|
||||
dev->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
|
||||
dev->i2c_adap.dev.parent = &pdev->dev;
|
||||
dev->i2c_adap.algo = &dm1105_algo;
|
||||
dev->i2c_adap.algo_data = dev;
|
||||
|
|
|
|||
|
|
@ -702,7 +702,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
|
|||
|
||||
kthread_stop(fepriv->thread);
|
||||
|
||||
init_MUTEX (&fepriv->sem);
|
||||
sema_init(&fepriv->sem, 1);
|
||||
fepriv->state = FESTATE_IDLE;
|
||||
|
||||
/* paranoia check in case a signal arrived */
|
||||
|
|
@ -2062,7 +2062,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
|
|||
}
|
||||
fepriv = fe->frontend_priv;
|
||||
|
||||
init_MUTEX (&fepriv->sem);
|
||||
sema_init(&fepriv->sem, 1);
|
||||
init_waitqueue_head (&fepriv->wait_queue);
|
||||
init_waitqueue_head (&fepriv->events.wait_queue);
|
||||
mutex_init(&fepriv->events.mtx);
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ struct dvb_frontend_ops {
|
|||
int (*init)(struct dvb_frontend* fe);
|
||||
int (*sleep)(struct dvb_frontend* fe);
|
||||
|
||||
int (*write)(struct dvb_frontend* fe, u8* buf, int len);
|
||||
int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
|
||||
|
||||
/* if this is set, it overrides the default swzigzag */
|
||||
int (*tune)(struct dvb_frontend* fe,
|
||||
|
|
|
|||
|
|
@ -314,6 +314,8 @@ config DVB_USB_AF9015
|
|||
select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
|
||||
|
||||
|
|
@ -346,3 +348,13 @@ config DVB_USB_AZ6027
|
|||
select DVB_STB6100 if !DVB_FE_CUSTOMISE
|
||||
help
|
||||
Say Y here to support the AZ6027 device
|
||||
|
||||
config DVB_USB_LME2510
|
||||
tristate "LME DM04/QQBOX DVB-S USB2.0 support"
|
||||
depends on DVB_USB
|
||||
select DVB_TDA10086 if !DVB_FE_CUSTOMISE
|
||||
select DVB_TDA826X if !DVB_FE_CUSTOMISE
|
||||
select DVB_STV0288 if !DVB_FE_CUSTOMISE
|
||||
select DVB_IX2505V if !DVB_FE_CUSTOMISE
|
||||
help
|
||||
Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
|
|||
dvb-usb-az6027-objs = az6027.o
|
||||
obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
|
||||
|
||||
dvb-usb-lmedm04-objs = lmedm04.o
|
||||
obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
|
||||
# due to tuner-xc3028
|
||||
EXTRA_CFLAGS += -Idrivers/media/common/tuners
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
#include "tda18271.h"
|
||||
#include "mxl5005s.h"
|
||||
#include "mc44s803.h"
|
||||
#include "tda18218.h"
|
||||
#include "mxl5007t.h"
|
||||
|
||||
static int dvb_usb_af9015_debug;
|
||||
module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
|
||||
|
|
@ -205,10 +207,16 @@ static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
|
|||
return af9015_write_regs(d, addr, &val, 1);
|
||||
}
|
||||
|
||||
static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
|
||||
{
|
||||
struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
|
||||
val};
|
||||
return af9015_ctrl_msg(d, &req);
|
||||
}
|
||||
|
||||
static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
|
||||
{
|
||||
struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val};
|
||||
return af9015_ctrl_msg(d, &req);
|
||||
return af9015_read_regs(d, addr, val, 1);
|
||||
}
|
||||
|
||||
static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
|
||||
|
|
@ -241,7 +249,7 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
int ret = 0, i = 0;
|
||||
u16 addr;
|
||||
u8 mbox, addr_len;
|
||||
u8 uninitialized_var(mbox), addr_len;
|
||||
struct req_t req;
|
||||
|
||||
/* TODO: implement bus lock
|
||||
|
|
@ -280,7 +288,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate.
|
|||
} else {
|
||||
addr = msg[i].buf[0];
|
||||
addr_len = 1;
|
||||
mbox = 0;
|
||||
/* mbox is don't care in that case */
|
||||
}
|
||||
|
||||
if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
|
||||
|
|
@ -494,7 +502,8 @@ static int af9015_copy_firmware(struct dvb_usb_device *d)
|
|||
/* wait 2nd demodulator ready */
|
||||
msleep(100);
|
||||
|
||||
ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val);
|
||||
ret = af9015_read_reg_i2c(d,
|
||||
af9015_af9013_config[1].demod_address, 0x98be, &val);
|
||||
if (ret)
|
||||
goto error;
|
||||
else
|
||||
|
|
@ -597,37 +606,6 @@ free:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int af9015_download_ir_table(struct dvb_usb_device *d)
|
||||
{
|
||||
int i, packets = 0, ret;
|
||||
u16 addr = 0x9a56; /* ir-table start address */
|
||||
struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL};
|
||||
u8 *data = NULL;
|
||||
deb_info("%s:\n", __func__);
|
||||
|
||||
data = af9015_config.ir_table;
|
||||
packets = af9015_config.ir_table_size;
|
||||
|
||||
/* no remote */
|
||||
if (!packets)
|
||||
goto exit;
|
||||
|
||||
/* load remote ir-table */
|
||||
for (i = 0; i < packets; i++) {
|
||||
req.addr = addr + i;
|
||||
req.data = &data[i];
|
||||
ret = af9015_ctrl_msg(d, &req);
|
||||
if (ret) {
|
||||
err("ir-table download failed at packet %d with " \
|
||||
"code %d", i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af9015_init(struct dvb_usb_device *d)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -637,10 +615,6 @@ static int af9015_init(struct dvb_usb_device *d)
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = af9015_download_ir_table(d);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -733,125 +707,102 @@ error:
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct af9015_setup {
|
||||
struct af9015_rc_setup {
|
||||
unsigned int id;
|
||||
struct ir_scancode *rc_key_map;
|
||||
unsigned int rc_key_map_size;
|
||||
u8 *ir_table;
|
||||
unsigned int ir_table_size;
|
||||
char *rc_codes;
|
||||
};
|
||||
|
||||
static const struct af9015_setup *af9015_setup_match(unsigned int id,
|
||||
const struct af9015_setup *table)
|
||||
static char *af9015_rc_setup_match(unsigned int id,
|
||||
const struct af9015_rc_setup *table)
|
||||
{
|
||||
for (; table->rc_key_map; table++)
|
||||
for (; table->rc_codes; table++)
|
||||
if (table->id == id)
|
||||
return table;
|
||||
return table->rc_codes;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct af9015_setup af9015_setup_modparam[] = {
|
||||
{ AF9015_REMOTE_A_LINK_DTU_M,
|
||||
ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link),
|
||||
af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
|
||||
{ AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
|
||||
ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi),
|
||||
af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
|
||||
{ AF9015_REMOTE_MYGICTV_U718,
|
||||
ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv),
|
||||
af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
|
||||
{ AF9015_REMOTE_DIGITTRADE_DVB_T,
|
||||
ir_codes_af9015_table_digittrade, ARRAY_SIZE(ir_codes_af9015_table_digittrade),
|
||||
af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) },
|
||||
{ AF9015_REMOTE_AVERMEDIA_KS,
|
||||
ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia),
|
||||
af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) },
|
||||
static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
|
||||
{ AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
|
||||
{ AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
|
||||
{ AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
|
||||
{ AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
|
||||
{ AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
|
||||
{ }
|
||||
};
|
||||
|
||||
/* don't add new entries here anymore, use hashes instead */
|
||||
static const struct af9015_setup af9015_setup_usbids[] = {
|
||||
{ USB_VID_LEADTEK,
|
||||
ir_codes_af9015_table_leadtek, ARRAY_SIZE(ir_codes_af9015_table_leadtek),
|
||||
af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) },
|
||||
{ USB_VID_VISIONPLUS,
|
||||
ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan),
|
||||
af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) },
|
||||
{ USB_VID_KWORLD_2, /* TODO: use correct rc keys */
|
||||
ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan),
|
||||
af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) },
|
||||
{ USB_VID_AVERMEDIA,
|
||||
ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia),
|
||||
af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) },
|
||||
{ USB_VID_MSI_2,
|
||||
ir_codes_af9015_table_msi_digivox_iii, ARRAY_SIZE(ir_codes_af9015_table_msi_digivox_iii),
|
||||
af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) },
|
||||
static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
|
||||
{ 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
|
||||
{ 0xa3703d00, RC_MAP_ALINK_DTU_M },
|
||||
{ 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct af9015_setup af9015_setup_hashes[] = {
|
||||
{ 0xb8feb708,
|
||||
ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi),
|
||||
af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
|
||||
{ 0xa3703d00,
|
||||
ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link),
|
||||
af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
|
||||
{ 0x9b7dc64e,
|
||||
ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv),
|
||||
af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
|
||||
static const struct af9015_rc_setup af9015_rc_setup_usbids[] = {
|
||||
{ (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
|
||||
RC_MAP_TERRATEC_SLIM },
|
||||
{ (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700,
|
||||
RC_MAP_AZUREWAVE_AD_TU700 },
|
||||
{ (USB_VID_VISIONPLUS << 16) + USB_PID_TINYTWIN,
|
||||
RC_MAP_AZUREWAVE_AD_TU700 },
|
||||
{ (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGI_VOX_MINI_III,
|
||||
RC_MAP_MSI_DIGIVOX_III },
|
||||
{ (USB_VID_LEADTEK << 16) + USB_PID_WINFAST_DTV_DONGLE_GOLD,
|
||||
RC_MAP_LEADTEK_Y04G0051 },
|
||||
{ (USB_VID_AVERMEDIA << 16) + USB_PID_AVERMEDIA_VOLAR_X,
|
||||
RC_MAP_AVERMEDIA_M135A },
|
||||
{ (USB_VID_AFATECH << 16) + USB_PID_TREKSTOR_DVBT,
|
||||
RC_MAP_TREKSTOR },
|
||||
{ (USB_VID_KWORLD_2 << 16) + USB_PID_TINYTWIN_2,
|
||||
RC_MAP_DIGITALNOW_TINYTWIN },
|
||||
{ (USB_VID_GTEK << 16) + USB_PID_TINYTWIN_3,
|
||||
RC_MAP_DIGITALNOW_TINYTWIN },
|
||||
{ }
|
||||
};
|
||||
|
||||
static void af9015_set_remote_config(struct usb_device *udev,
|
||||
struct dvb_usb_device_properties *props)
|
||||
{
|
||||
const struct af9015_setup *table = NULL;
|
||||
u16 vid = le16_to_cpu(udev->descriptor.idVendor);
|
||||
u16 pid = le16_to_cpu(udev->descriptor.idProduct);
|
||||
|
||||
if (dvb_usb_af9015_remote) {
|
||||
/* load remote defined as module param */
|
||||
table = af9015_setup_match(dvb_usb_af9015_remote,
|
||||
af9015_setup_modparam);
|
||||
} else {
|
||||
u16 vendor = le16_to_cpu(udev->descriptor.idVendor);
|
||||
/* try to load remote based module param */
|
||||
props->rc.core.rc_codes = af9015_rc_setup_match(
|
||||
dvb_usb_af9015_remote, af9015_rc_setup_modparam);
|
||||
|
||||
table = af9015_setup_match(af9015_config.eeprom_sum,
|
||||
af9015_setup_hashes);
|
||||
/* try to load remote based eeprom hash */
|
||||
if (!props->rc.core.rc_codes)
|
||||
props->rc.core.rc_codes = af9015_rc_setup_match(
|
||||
af9015_config.eeprom_sum, af9015_rc_setup_hashes);
|
||||
|
||||
if (!table && vendor == USB_VID_AFATECH) {
|
||||
/* Check USB manufacturer and product strings and try
|
||||
to determine correct remote in case of chip vendor
|
||||
reference IDs are used.
|
||||
DO NOT ADD ANYTHING NEW HERE. Use hashes instead.
|
||||
*/
|
||||
char manufacturer[10];
|
||||
memset(manufacturer, 0, sizeof(manufacturer));
|
||||
usb_string(udev, udev->descriptor.iManufacturer,
|
||||
manufacturer, sizeof(manufacturer));
|
||||
if (!strcmp("MSI", manufacturer)) {
|
||||
/* iManufacturer 1 MSI
|
||||
iProduct 2 MSI K-VOX */
|
||||
table = af9015_setup_match(
|
||||
AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
|
||||
af9015_setup_modparam);
|
||||
} else if (udev->descriptor.idProduct ==
|
||||
cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
|
||||
table = &(const struct af9015_setup){ 0,
|
||||
ir_codes_af9015_table_trekstor,
|
||||
ARRAY_SIZE(ir_codes_af9015_table_trekstor),
|
||||
af9015_ir_table_trekstor,
|
||||
ARRAY_SIZE(af9015_ir_table_trekstor)
|
||||
};
|
||||
}
|
||||
} else if (!table)
|
||||
table = af9015_setup_match(vendor, af9015_setup_usbids);
|
||||
/* try to load remote based USB ID */
|
||||
if (!props->rc.core.rc_codes)
|
||||
props->rc.core.rc_codes = af9015_rc_setup_match(
|
||||
(vid << 16) + pid, af9015_rc_setup_usbids);
|
||||
|
||||
/* try to load remote based USB iManufacturer string */
|
||||
if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) {
|
||||
/* Check USB manufacturer and product strings and try
|
||||
to determine correct remote in case of chip vendor
|
||||
reference IDs are used.
|
||||
DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
|
||||
char manufacturer[10];
|
||||
memset(manufacturer, 0, sizeof(manufacturer));
|
||||
usb_string(udev, udev->descriptor.iManufacturer,
|
||||
manufacturer, sizeof(manufacturer));
|
||||
if (!strcmp("MSI", manufacturer)) {
|
||||
/* iManufacturer 1 MSI
|
||||
iProduct 2 MSI K-VOX */
|
||||
props->rc.core.rc_codes = af9015_rc_setup_match(
|
||||
AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
|
||||
af9015_rc_setup_modparam);
|
||||
}
|
||||
}
|
||||
|
||||
if (table) {
|
||||
props->rc.legacy.rc_key_map = table->rc_key_map;
|
||||
props->rc.legacy.rc_key_map_size = table->rc_key_map_size;
|
||||
af9015_config.ir_table = table->ir_table;
|
||||
af9015_config.ir_table_size = table->ir_table_size;
|
||||
}
|
||||
/* finally load "empty" just for leaving IR receiver enabled */
|
||||
if (!props->rc.core.rc_codes)
|
||||
props->rc.core.rc_codes = RC_MAP_EMPTY;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int af9015_read_config(struct usb_device *udev)
|
||||
|
|
@ -877,10 +828,9 @@ static int af9015_read_config(struct usb_device *udev)
|
|||
|
||||
deb_info("%s: IR mode:%d\n", __func__, val);
|
||||
for (i = 0; i < af9015_properties_count; i++) {
|
||||
if (val == AF9015_IR_MODE_DISABLED) {
|
||||
af9015_properties[i].rc.legacy.rc_key_map = NULL;
|
||||
af9015_properties[i].rc.legacy.rc_key_map_size = 0;
|
||||
} else
|
||||
if (val == AF9015_IR_MODE_DISABLED)
|
||||
af9015_properties[i].rc.core.rc_codes = NULL;
|
||||
else
|
||||
af9015_set_remote_config(udev, &af9015_properties[i]);
|
||||
}
|
||||
|
||||
|
|
@ -992,20 +942,19 @@ static int af9015_read_config(struct usb_device *udev)
|
|||
case AF9013_TUNER_MT2060_2:
|
||||
case AF9013_TUNER_TDA18271:
|
||||
case AF9013_TUNER_QT1010A:
|
||||
case AF9013_TUNER_TDA18218:
|
||||
af9015_af9013_config[i].rf_spec_inv = 1;
|
||||
break;
|
||||
case AF9013_TUNER_MXL5003D:
|
||||
case AF9013_TUNER_MXL5005D:
|
||||
case AF9013_TUNER_MXL5005R:
|
||||
case AF9013_TUNER_MXL5007T:
|
||||
af9015_af9013_config[i].rf_spec_inv = 0;
|
||||
break;
|
||||
case AF9013_TUNER_MC44S803:
|
||||
af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
|
||||
af9015_af9013_config[i].rf_spec_inv = 1;
|
||||
break;
|
||||
case AF9013_TUNER_TDA18218:
|
||||
warn("tuner NXP TDA18218 not supported yet");
|
||||
return -ENODEV;
|
||||
default:
|
||||
warn("tuner id:%d not supported, please report!", val);
|
||||
return -ENODEV;
|
||||
|
|
@ -1020,9 +969,13 @@ error:
|
|||
err("eeprom read failed:%d", ret);
|
||||
|
||||
/* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
|
||||
content :-( Override some wrong values here. */
|
||||
content :-( Override some wrong values here. Ditto for the
|
||||
AVerTV Red HD+ (A850T) device. */
|
||||
if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
|
||||
le16_to_cpu(udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) {
|
||||
((le16_to_cpu(udev->descriptor.idProduct) ==
|
||||
USB_PID_AVERMEDIA_A850) ||
|
||||
(le16_to_cpu(udev->descriptor.idProduct) ==
|
||||
USB_PID_AVERMEDIA_A850T))) {
|
||||
deb_info("%s: AverMedia A850: overriding config\n", __func__);
|
||||
/* disable dual mode */
|
||||
af9015_config.dual_mode = 0;
|
||||
|
|
@ -1059,36 +1012,53 @@ static int af9015_identify_state(struct usb_device *udev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
||||
static int af9015_rc_query(struct dvb_usb_device *d)
|
||||
{
|
||||
u8 buf[8];
|
||||
struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf};
|
||||
struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
|
||||
int i, ret;
|
||||
struct af9015_state *priv = d->priv;
|
||||
int ret;
|
||||
u8 buf[16];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
ret = af9015_ctrl_msg(d, &req);
|
||||
/* read registers needed to detect remote controller code */
|
||||
ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
|
||||
if (ret)
|
||||
return ret;
|
||||
goto error;
|
||||
|
||||
*event = 0;
|
||||
*state = REMOTE_NO_KEY_PRESSED;
|
||||
if (buf[14] || buf[15]) {
|
||||
deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
|
||||
buf[12], buf[13], buf[14], buf[15]);
|
||||
|
||||
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
|
||||
if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] &&
|
||||
rc5_data(&keymap[i]) == buf[2]) {
|
||||
*event = keymap[i].keycode;
|
||||
*state = REMOTE_KEY_PRESSED;
|
||||
break;
|
||||
/* clean IR code from mem */
|
||||
ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (buf[14] == (u8) ~buf[15]) {
|
||||
if (buf[12] == (u8) ~buf[13]) {
|
||||
/* NEC */
|
||||
priv->rc_keycode = buf[12] << 8 | buf[14];
|
||||
} else {
|
||||
/* NEC extended*/
|
||||
priv->rc_keycode = buf[12] << 16 |
|
||||
buf[13] << 8 | buf[14];
|
||||
}
|
||||
ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
|
||||
} else {
|
||||
priv->rc_keycode = 0; /* clear just for sure */
|
||||
}
|
||||
} else if (priv->rc_repeat != buf[6] || buf[0]) {
|
||||
deb_rc("%s: key repeated\n", __func__);
|
||||
ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
|
||||
} else {
|
||||
deb_rc("%s: no key press\n", __func__);
|
||||
}
|
||||
if (!buf[1])
|
||||
deb_rc("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
__func__, buf[0], buf[1], buf[2], buf[3], buf[4],
|
||||
buf[5], buf[6], buf[7]);
|
||||
|
||||
return 0;
|
||||
priv->rc_repeat = buf[6];
|
||||
|
||||
error:
|
||||
if (ret)
|
||||
err("%s: failed:%d", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* init 2nd I2C adapter */
|
||||
|
|
@ -1100,11 +1070,6 @@ static int af9015_i2c_init(struct dvb_usb_device *d)
|
|||
|
||||
strncpy(state->i2c_adap.name, d->desc->name,
|
||||
sizeof(state->i2c_adap.name));
|
||||
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
|
||||
state->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
|
||||
#else
|
||||
state->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
|
||||
#endif
|
||||
state->i2c_adap.algo = d->props.i2c_algo;
|
||||
state->i2c_adap.algo_data = NULL;
|
||||
state->i2c_adap.dev.parent = &d->udev->dev;
|
||||
|
|
@ -1166,7 +1131,7 @@ static struct qt1010_config af9015_qt1010_config = {
|
|||
|
||||
static struct tda18271_config af9015_tda18271_config = {
|
||||
.gate = TDA18271_GATE_DIGITAL,
|
||||
.small_i2c = 1,
|
||||
.small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
|
||||
};
|
||||
|
||||
static struct mxl5005s_config af9015_mxl5003_config = {
|
||||
|
|
@ -1208,12 +1173,22 @@ static struct mc44s803_config af9015_mc44s803_config = {
|
|||
.dig_out = 1,
|
||||
};
|
||||
|
||||
static struct tda18218_config af9015_tda18218_config = {
|
||||
.i2c_address = 0xc0,
|
||||
.i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
|
||||
};
|
||||
|
||||
static struct mxl5007t_config af9015_mxl5007t_config = {
|
||||
.xtal_freq_hz = MxL_XTAL_24_MHZ,
|
||||
.if_freq_hz = MxL_IF_4_57_MHZ,
|
||||
};
|
||||
|
||||
static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct af9015_state *state = adap->dev->priv;
|
||||
struct i2c_adapter *i2c_adap;
|
||||
int ret;
|
||||
deb_info("%s: \n", __func__);
|
||||
deb_info("%s:\n", __func__);
|
||||
|
||||
/* select I2C adapter */
|
||||
if (adap->id == 0)
|
||||
|
|
@ -1238,6 +1213,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap,
|
||||
&af9015_tda18271_config) == NULL ? -ENODEV : 0;
|
||||
break;
|
||||
case AF9013_TUNER_TDA18218:
|
||||
ret = dvb_attach(tda18218_attach, adap->fe, i2c_adap,
|
||||
&af9015_tda18218_config) == NULL ? -ENODEV : 0;
|
||||
break;
|
||||
case AF9013_TUNER_MXL5003D:
|
||||
ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap,
|
||||
&af9015_mxl5003_config) == NULL ? -ENODEV : 0;
|
||||
|
|
@ -1255,6 +1234,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
|
||||
&af9015_mc44s803_config) == NULL ? -ENODEV : 0;
|
||||
break;
|
||||
case AF9013_TUNER_MXL5007T:
|
||||
ret = dvb_attach(mxl5007t_attach, adap->fe, i2c_adap,
|
||||
0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
|
||||
break;
|
||||
case AF9013_TUNER_UNKNOWN:
|
||||
default:
|
||||
ret = -ENODEV;
|
||||
|
|
@ -1300,10 +1283,16 @@ static struct usb_device_id af9015_usb_table[] = {
|
|||
/* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
|
||||
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
|
||||
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
|
||||
{USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
|
||||
{USB_DEVICE(USB_VID_TERRATEC,
|
||||
USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)},
|
||||
/* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)},
|
||||
{USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)},
|
||||
{0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
|
||||
|
||||
#define AF9015_RC_INTERVAL 500
|
||||
static struct dvb_usb_device_properties af9015_properties[] = {
|
||||
{
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
|
|
@ -1354,14 +1343,19 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
|
||||
.identify_state = af9015_identify_state,
|
||||
|
||||
.rc.legacy = {
|
||||
.rc.core = {
|
||||
.protocol = IR_TYPE_NEC,
|
||||
.module_name = "af9015",
|
||||
.rc_query = af9015_rc_query,
|
||||
.rc_interval = 150,
|
||||
.rc_interval = AF9015_RC_INTERVAL,
|
||||
.rc_props = {
|
||||
.allowed_protos = IR_TYPE_NEC,
|
||||
},
|
||||
},
|
||||
|
||||
.i2c_algo = &af9015_i2c_algo,
|
||||
|
||||
.num_device_descs = 9, /* max 9 */
|
||||
.num_device_descs = 12, /* check max from dvb-usb.h */
|
||||
.devices = {
|
||||
{
|
||||
.name = "Afatech AF9015 DVB-T USB2.0 stick",
|
||||
|
|
@ -1389,7 +1383,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
{
|
||||
.name = "DigitalNow TinyTwin DVB-T Receiver",
|
||||
.cold_ids = {&af9015_usb_table[5],
|
||||
&af9015_usb_table[28], NULL},
|
||||
&af9015_usb_table[28],
|
||||
&af9015_usb_table[36], NULL},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
|
|
@ -1413,6 +1408,21 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
.cold_ids = {&af9015_usb_table[9], NULL},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
.name = "TerraTec Cinergy T Stick RC",
|
||||
.cold_ids = {&af9015_usb_table[33], NULL},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
.name = "TerraTec Cinergy T Stick Dual RC",
|
||||
.cold_ids = {&af9015_usb_table[34], NULL},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
.name = "AverMedia AVerTV Red HD+ (A850T)",
|
||||
.cold_ids = {&af9015_usb_table[35], NULL},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
}
|
||||
}, {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
|
|
@ -1463,14 +1473,19 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
|
||||
.identify_state = af9015_identify_state,
|
||||
|
||||
.rc.legacy = {
|
||||
.rc.core = {
|
||||
.protocol = IR_TYPE_NEC,
|
||||
.module_name = "af9015",
|
||||
.rc_query = af9015_rc_query,
|
||||
.rc_interval = 150,
|
||||
.rc_interval = AF9015_RC_INTERVAL,
|
||||
.rc_props = {
|
||||
.allowed_protos = IR_TYPE_NEC,
|
||||
},
|
||||
},
|
||||
|
||||
.i2c_algo = &af9015_i2c_algo,
|
||||
|
||||
.num_device_descs = 9, /* max 9 */
|
||||
.num_device_descs = 9, /* check max from dvb-usb.h */
|
||||
.devices = {
|
||||
{
|
||||
.name = "Xtensions XD-380",
|
||||
|
|
@ -1572,14 +1587,19 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
|
||||
.identify_state = af9015_identify_state,
|
||||
|
||||
.rc.legacy = {
|
||||
.rc.core = {
|
||||
.protocol = IR_TYPE_NEC,
|
||||
.module_name = "af9015",
|
||||
.rc_query = af9015_rc_query,
|
||||
.rc_interval = 150,
|
||||
.rc_interval = AF9015_RC_INTERVAL,
|
||||
.rc_props = {
|
||||
.allowed_protos = IR_TYPE_NEC,
|
||||
},
|
||||
},
|
||||
|
||||
.i2c_algo = &af9015_i2c_algo,
|
||||
|
||||
.num_device_descs = 9, /* max 9 */
|
||||
.num_device_descs = 9, /* check max from dvb-usb.h */
|
||||
.devices = {
|
||||
{
|
||||
.name = "AverMedia AVerTV Volar GPS 805 (A805)",
|
||||
|
|
@ -1672,7 +1692,7 @@ static int af9015_usb_probe(struct usb_interface *intf,
|
|||
static void af9015_i2c_exit(struct dvb_usb_device *d)
|
||||
{
|
||||
struct af9015_state *state = d->priv;
|
||||
deb_info("%s: \n", __func__);
|
||||
deb_info("%s:\n", __func__);
|
||||
|
||||
/* remove 2nd I2C adapter */
|
||||
if (d->state & DVB_USB_STATE_I2C)
|
||||
|
|
@ -1682,7 +1702,7 @@ static void af9015_i2c_exit(struct dvb_usb_device *d)
|
|||
static void af9015_usb_device_exit(struct usb_interface *intf)
|
||||
{
|
||||
struct dvb_usb_device *d = usb_get_intfdata(intf);
|
||||
deb_info("%s: \n", __func__);
|
||||
deb_info("%s:\n", __func__);
|
||||
|
||||
/* remove 2nd I2C adapter */
|
||||
if (d != NULL && d->desc != NULL)
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ enum af9015_ir_mode {
|
|||
|
||||
struct af9015_state {
|
||||
struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */
|
||||
u8 rc_repeat;
|
||||
u32 rc_keycode;
|
||||
};
|
||||
|
||||
struct af9015_config {
|
||||
|
|
@ -108,8 +110,6 @@ struct af9015_config {
|
|||
u16 firmware_size;
|
||||
u16 firmware_checksum;
|
||||
u32 eeprom_sum;
|
||||
u8 *ir_table;
|
||||
u16 ir_table_size;
|
||||
};
|
||||
|
||||
enum af9015_remote {
|
||||
|
|
@ -121,735 +121,4 @@ enum af9015_remote {
|
|||
/* 5 */ AF9015_REMOTE_AVERMEDIA_KS,
|
||||
};
|
||||
|
||||
/* LeadTek - Y04G0051 */
|
||||
/* Leadtek WinFast DTV Dongle Gold */
|
||||
static struct ir_scancode ir_codes_af9015_table_leadtek[] = {
|
||||
{ 0x001e, KEY_1 },
|
||||
{ 0x001f, KEY_2 },
|
||||
{ 0x0020, KEY_3 },
|
||||
{ 0x0021, KEY_4 },
|
||||
{ 0x0022, KEY_5 },
|
||||
{ 0x0023, KEY_6 },
|
||||
{ 0x0024, KEY_7 },
|
||||
{ 0x0025, KEY_8 },
|
||||
{ 0x0026, KEY_9 },
|
||||
{ 0x0027, KEY_0 },
|
||||
{ 0x0028, KEY_OK },
|
||||
{ 0x004f, KEY_RIGHT },
|
||||
{ 0x0050, KEY_LEFT },
|
||||
{ 0x0051, KEY_DOWN },
|
||||
{ 0x0052, KEY_UP },
|
||||
{ 0x011a, KEY_POWER2 },
|
||||
{ 0x04b4, KEY_TV },
|
||||
{ 0x04b3, KEY_RED },
|
||||
{ 0x04b2, KEY_GREEN },
|
||||
{ 0x04b1, KEY_YELLOW },
|
||||
{ 0x04b0, KEY_BLUE },
|
||||
{ 0x003d, KEY_TEXT },
|
||||
{ 0x0113, KEY_SLEEP },
|
||||
{ 0x0010, KEY_MUTE },
|
||||
{ 0x0105, KEY_ESC },
|
||||
{ 0x0009, KEY_SCREEN },
|
||||
{ 0x010f, KEY_MENU },
|
||||
{ 0x003f, KEY_CHANNEL },
|
||||
{ 0x0013, KEY_REWIND },
|
||||
{ 0x0012, KEY_PLAY },
|
||||
{ 0x0011, KEY_FASTFORWARD },
|
||||
{ 0x0005, KEY_PREVIOUS },
|
||||
{ 0x0029, KEY_STOP },
|
||||
{ 0x002b, KEY_NEXT },
|
||||
{ 0x0041, KEY_EPG },
|
||||
{ 0x0019, KEY_VIDEO },
|
||||
{ 0x0016, KEY_AUDIO },
|
||||
{ 0x0037, KEY_DOT },
|
||||
{ 0x002a, KEY_AGAIN },
|
||||
{ 0x002c, KEY_CAMERA },
|
||||
{ 0x003c, KEY_NEW },
|
||||
{ 0x0115, KEY_RECORD },
|
||||
{ 0x010b, KEY_TIME },
|
||||
{ 0x0043, KEY_VOLUMEUP },
|
||||
{ 0x0042, KEY_VOLUMEDOWN },
|
||||
{ 0x004b, KEY_CHANNELUP },
|
||||
{ 0x004e, KEY_CHANNELDOWN },
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_leadtek[] = {
|
||||
0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, /* KEY_POWER2 */
|
||||
0x03, 0xfc, 0x56, 0xa9, 0xb4, 0x04, 0x00, /* KEY_TV */
|
||||
0x03, 0xfc, 0x4b, 0xb4, 0xb3, 0x04, 0x00, /* KEY_RED */
|
||||
0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, /* KEY_GREEN */
|
||||
0x03, 0xfc, 0x4d, 0xb2, 0xb1, 0x04, 0x00, /* KEY_YELLOW */
|
||||
0x03, 0xfc, 0x4e, 0xb1, 0xb0, 0x04, 0x00, /* KEY_BLUE */
|
||||
0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, /* KEY_TEXT */
|
||||
0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, /* KEY_SLEEP */
|
||||
0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, /* KEY_MUTE */
|
||||
0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, /* KEY_ESC */
|
||||
0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, /* KEY_STOP (1)*/
|
||||
0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, /* KEY_UP */
|
||||
0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, /* KEY_SCREEN */
|
||||
0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, /* KEY_LEFT */
|
||||
0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, /* KEY_OK (1) */
|
||||
0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, /* KEY_RIGHT */
|
||||
0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, /* KEY_MENU */
|
||||
0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, /* KEY_DOWN */
|
||||
0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, /* KEY_CHANNEL */
|
||||
0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, /* KEY_REWIND */
|
||||
0x03, 0xfc, 0x43, 0xbc, 0x12, 0x00, 0x00, /* KEY_PLAY */
|
||||
0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, /* KEY_FASTFORWARD */
|
||||
0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, /* KEY_VIDEO (1) */
|
||||
0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, /* KEY_PREVIOUS */
|
||||
0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, /* KEY_STOP (2) */
|
||||
0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, /* KEY_NEXT */
|
||||
0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, /* KEY_EPG */
|
||||
0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, /* KEY_1 */
|
||||
0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, /* KEY_2 */
|
||||
0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, /* KEY_3 */
|
||||
0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, /* KEY_VIDEO (2) */
|
||||
0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, /* KEY_4 */
|
||||
0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, /* KEY_5 */
|
||||
0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, /* KEY_6 */
|
||||
0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, /* KEY_AUDIO */
|
||||
0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, /* KEY_7 */
|
||||
0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, /* KEY_8 */
|
||||
0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, /* KEY_9 */
|
||||
0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* KEY_OK (2) */
|
||||
0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, /* KEY_DOT */
|
||||
0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, /* KEY_0 */
|
||||
0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, /* KEY_AGAIN */
|
||||
0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, /* KEY_CAMERA */
|
||||
0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, /* KEY_NEW */
|
||||
0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, /* KEY_RECORD */
|
||||
0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, /* KEY_TIME */
|
||||
0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, /* KEY_VOLUMEUP */
|
||||
0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, /* KEY_VOLUMEDOWN */
|
||||
0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, /* KEY_CHANNELUP */
|
||||
0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, /* KEY_CHANNELDOWN */
|
||||
};
|
||||
|
||||
/* TwinHan AzureWave AD-TU700(704J) */
|
||||
static struct ir_scancode ir_codes_af9015_table_twinhan[] = {
|
||||
{ 0x053f, KEY_POWER },
|
||||
{ 0x0019, KEY_FAVORITES }, /* Favorite List */
|
||||
{ 0x0004, KEY_TEXT }, /* Teletext */
|
||||
{ 0x000e, KEY_POWER },
|
||||
{ 0x000e, KEY_INFO }, /* Preview */
|
||||
{ 0x0008, KEY_EPG }, /* Info/EPG */
|
||||
{ 0x000f, KEY_LIST }, /* Record List */
|
||||
{ 0x001e, KEY_1 },
|
||||
{ 0x001f, KEY_2 },
|
||||
{ 0x0020, KEY_3 },
|
||||
{ 0x0021, KEY_4 },
|
||||
{ 0x0022, KEY_5 },
|
||||
{ 0x0023, KEY_6 },
|
||||
{ 0x0024, KEY_7 },
|
||||
{ 0x0025, KEY_8 },
|
||||
{ 0x0026, KEY_9 },
|
||||
{ 0x0027, KEY_0 },
|
||||
{ 0x0029, KEY_CANCEL }, /* Cancel */
|
||||
{ 0x004c, KEY_CLEAR }, /* Clear */
|
||||
{ 0x002a, KEY_BACK }, /* Back */
|
||||
{ 0x002b, KEY_TAB }, /* Tab */
|
||||
{ 0x0052, KEY_UP }, /* up arrow */
|
||||
{ 0x0051, KEY_DOWN }, /* down arrow */
|
||||
{ 0x004f, KEY_RIGHT }, /* right arrow */
|
||||
{ 0x0050, KEY_LEFT }, /* left arrow */
|
||||
{ 0x0028, KEY_ENTER }, /* Enter / ok */
|
||||
{ 0x0252, KEY_VOLUMEUP },
|
||||
{ 0x0251, KEY_VOLUMEDOWN },
|
||||
{ 0x004e, KEY_CHANNELDOWN },
|
||||
{ 0x004b, KEY_CHANNELUP },
|
||||
{ 0x004a, KEY_RECORD },
|
||||
{ 0x0111, KEY_PLAY },
|
||||
{ 0x0017, KEY_PAUSE },
|
||||
{ 0x000c, KEY_REWIND }, /* FR << */
|
||||
{ 0x0011, KEY_FASTFORWARD }, /* FF >> */
|
||||
{ 0x0115, KEY_PREVIOUS }, /* Replay */
|
||||
{ 0x010e, KEY_NEXT }, /* Skip */
|
||||
{ 0x0013, KEY_CAMERA }, /* Capture */
|
||||
{ 0x010f, KEY_LANGUAGE }, /* SAP */
|
||||
{ 0x0113, KEY_TV2 }, /* PIP */
|
||||
{ 0x001d, KEY_ZOOM }, /* Full Screen */
|
||||
{ 0x0117, KEY_SUBTITLE }, /* Subtitle / CC */
|
||||
{ 0x0010, KEY_MUTE },
|
||||
{ 0x0119, KEY_AUDIO }, /* L/R */ /* TODO better event */
|
||||
{ 0x0116, KEY_SLEEP }, /* Hibernate */
|
||||
{ 0x0116, KEY_SWITCHVIDEOMODE },
|
||||
/* A/V */ /* TODO does not work */
|
||||
{ 0x0006, KEY_AGAIN }, /* Recall */
|
||||
{ 0x0116, KEY_KPPLUS }, /* Zoom+ */ /* TODO does not work */
|
||||
{ 0x0116, KEY_KPMINUS }, /* Zoom- */ /* TODO does not work */
|
||||
{ 0x0215, KEY_RED },
|
||||
{ 0x020a, KEY_GREEN },
|
||||
{ 0x021c, KEY_YELLOW },
|
||||
{ 0x0205, KEY_BLUE },
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_twinhan[] = {
|
||||
0x00, 0xff, 0x16, 0xe9, 0x3f, 0x05, 0x00,
|
||||
0x00, 0xff, 0x07, 0xf8, 0x16, 0x01, 0x00,
|
||||
0x00, 0xff, 0x14, 0xeb, 0x11, 0x01, 0x00,
|
||||
0x00, 0xff, 0x1a, 0xe5, 0x4d, 0x00, 0x00,
|
||||
0x00, 0xff, 0x4c, 0xb3, 0x17, 0x00, 0x00,
|
||||
0x00, 0xff, 0x12, 0xed, 0x11, 0x00, 0x00,
|
||||
0x00, 0xff, 0x40, 0xbf, 0x0c, 0x00, 0x00,
|
||||
0x00, 0xff, 0x11, 0xee, 0x4a, 0x00, 0x00,
|
||||
0x00, 0xff, 0x54, 0xab, 0x13, 0x00, 0x00,
|
||||
0x00, 0xff, 0x41, 0xbe, 0x15, 0x01, 0x00,
|
||||
0x00, 0xff, 0x42, 0xbd, 0x0e, 0x01, 0x00,
|
||||
0x00, 0xff, 0x43, 0xbc, 0x17, 0x01, 0x00,
|
||||
0x00, 0xff, 0x50, 0xaf, 0x0f, 0x01, 0x00,
|
||||
0x00, 0xff, 0x4d, 0xb2, 0x1d, 0x00, 0x00,
|
||||
0x00, 0xff, 0x47, 0xb8, 0x13, 0x01, 0x00,
|
||||
0x00, 0xff, 0x05, 0xfa, 0x4b, 0x00, 0x00,
|
||||
0x00, 0xff, 0x02, 0xfd, 0x4e, 0x00, 0x00,
|
||||
0x00, 0xff, 0x0e, 0xf1, 0x06, 0x00, 0x00,
|
||||
0x00, 0xff, 0x1e, 0xe1, 0x52, 0x02, 0x00,
|
||||
0x00, 0xff, 0x0a, 0xf5, 0x51, 0x02, 0x00,
|
||||
0x00, 0xff, 0x10, 0xef, 0x10, 0x00, 0x00,
|
||||
0x00, 0xff, 0x49, 0xb6, 0x19, 0x01, 0x00,
|
||||
0x00, 0xff, 0x15, 0xea, 0x27, 0x00, 0x00,
|
||||
0x00, 0xff, 0x03, 0xfc, 0x1e, 0x00, 0x00,
|
||||
0x00, 0xff, 0x01, 0xfe, 0x1f, 0x00, 0x00,
|
||||
0x00, 0xff, 0x06, 0xf9, 0x20, 0x00, 0x00,
|
||||
0x00, 0xff, 0x09, 0xf6, 0x21, 0x00, 0x00,
|
||||
0x00, 0xff, 0x1d, 0xe2, 0x22, 0x00, 0x00,
|
||||
0x00, 0xff, 0x1f, 0xe0, 0x23, 0x00, 0x00,
|
||||
0x00, 0xff, 0x0d, 0xf2, 0x24, 0x00, 0x00,
|
||||
0x00, 0xff, 0x19, 0xe6, 0x25, 0x00, 0x00,
|
||||
0x00, 0xff, 0x1b, 0xe4, 0x26, 0x00, 0x00,
|
||||
0x00, 0xff, 0x00, 0xff, 0x2b, 0x00, 0x00,
|
||||
0x00, 0xff, 0x4a, 0xb5, 0x4c, 0x00, 0x00,
|
||||
0x00, 0xff, 0x4b, 0xb4, 0x52, 0x00, 0x00,
|
||||
0x00, 0xff, 0x51, 0xae, 0x51, 0x00, 0x00,
|
||||
0x00, 0xff, 0x52, 0xad, 0x4f, 0x00, 0x00,
|
||||
0x00, 0xff, 0x4e, 0xb1, 0x50, 0x00, 0x00,
|
||||
0x00, 0xff, 0x0c, 0xf3, 0x29, 0x00, 0x00,
|
||||
0x00, 0xff, 0x4f, 0xb0, 0x28, 0x00, 0x00,
|
||||
0x00, 0xff, 0x13, 0xec, 0x2a, 0x00, 0x00,
|
||||
0x00, 0xff, 0x17, 0xe8, 0x19, 0x00, 0x00,
|
||||
0x00, 0xff, 0x04, 0xfb, 0x0f, 0x00, 0x00,
|
||||
0x00, 0xff, 0x48, 0xb7, 0x0e, 0x00, 0x00,
|
||||
0x00, 0xff, 0x0f, 0xf0, 0x04, 0x00, 0x00,
|
||||
0x00, 0xff, 0x1c, 0xe3, 0x08, 0x00, 0x00,
|
||||
0x00, 0xff, 0x18, 0xe7, 0x15, 0x02, 0x00,
|
||||
0x00, 0xff, 0x53, 0xac, 0x0a, 0x02, 0x00,
|
||||
0x00, 0xff, 0x5e, 0xa1, 0x1c, 0x02, 0x00,
|
||||
0x00, 0xff, 0x5f, 0xa0, 0x05, 0x02, 0x00,
|
||||
};
|
||||
|
||||
/* A-Link DTU(m) */
|
||||
static struct ir_scancode ir_codes_af9015_table_a_link[] = {
|
||||
{ 0x001e, KEY_1 },
|
||||
{ 0x001f, KEY_2 },
|
||||
{ 0x0020, KEY_3 },
|
||||
{ 0x0021, KEY_4 },
|
||||
{ 0x0022, KEY_5 },
|
||||
{ 0x0023, KEY_6 },
|
||||
{ 0x0024, KEY_7 },
|
||||
{ 0x0025, KEY_8 },
|
||||
{ 0x0026, KEY_9 },
|
||||
{ 0x0027, KEY_0 },
|
||||
{ 0x002e, KEY_CHANNELUP },
|
||||
{ 0x002d, KEY_CHANNELDOWN },
|
||||
{ 0x0428, KEY_ZOOM },
|
||||
{ 0x0041, KEY_MUTE },
|
||||
{ 0x0042, KEY_VOLUMEDOWN },
|
||||
{ 0x0043, KEY_VOLUMEUP },
|
||||
{ 0x0044, KEY_GOTO }, /* jump */
|
||||
{ 0x0545, KEY_POWER },
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_a_link[] = {
|
||||
0x08, 0xf7, 0x12, 0xed, 0x45, 0x05, 0x00, /* power */
|
||||
0x08, 0xf7, 0x1a, 0xe5, 0x41, 0x00, 0x00, /* mute */
|
||||
0x08, 0xf7, 0x01, 0xfe, 0x1e, 0x00, 0x00, /* 1 */
|
||||
0x08, 0xf7, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */
|
||||
0x08, 0xf7, 0x03, 0xfc, 0x24, 0x00, 0x00, /* 7 */
|
||||
0x08, 0xf7, 0x05, 0xfa, 0x28, 0x04, 0x00, /* zoom */
|
||||
0x08, 0xf7, 0x00, 0xff, 0x43, 0x00, 0x00, /* volume up */
|
||||
0x08, 0xf7, 0x16, 0xe9, 0x42, 0x00, 0x00, /* volume down */
|
||||
0x08, 0xf7, 0x0f, 0xf0, 0x1f, 0x00, 0x00, /* 2 */
|
||||
0x08, 0xf7, 0x0d, 0xf2, 0x22, 0x00, 0x00, /* 5 */
|
||||
0x08, 0xf7, 0x1b, 0xe4, 0x25, 0x00, 0x00, /* 8 */
|
||||
0x08, 0xf7, 0x06, 0xf9, 0x27, 0x00, 0x00, /* 0 */
|
||||
0x08, 0xf7, 0x14, 0xeb, 0x2e, 0x00, 0x00, /* channel up */
|
||||
0x08, 0xf7, 0x1d, 0xe2, 0x2d, 0x00, 0x00, /* channel down */
|
||||
0x08, 0xf7, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */
|
||||
0x08, 0xf7, 0x18, 0xe7, 0x23, 0x00, 0x00, /* 6 */
|
||||
0x08, 0xf7, 0x04, 0xfb, 0x26, 0x00, 0x00, /* 9 */
|
||||
0x08, 0xf7, 0x07, 0xf8, 0x44, 0x00, 0x00, /* jump */
|
||||
};
|
||||
|
||||
/* MSI DIGIVOX mini II V3.0 */
|
||||
static struct ir_scancode ir_codes_af9015_table_msi[] = {
|
||||
{ 0x001e, KEY_1 },
|
||||
{ 0x001f, KEY_2 },
|
||||
{ 0x0020, KEY_3 },
|
||||
{ 0x0021, KEY_4 },
|
||||
{ 0x0022, KEY_5 },
|
||||
{ 0x0023, KEY_6 },
|
||||
{ 0x0024, KEY_7 },
|
||||
{ 0x0025, KEY_8 },
|
||||
{ 0x0026, KEY_9 },
|
||||
{ 0x0027, KEY_0 },
|
||||
{ 0x030f, KEY_CHANNELUP },
|
||||
{ 0x030e, KEY_CHANNELDOWN },
|
||||
{ 0x0042, KEY_VOLUMEDOWN },
|
||||
{ 0x0043, KEY_VOLUMEUP },
|
||||
{ 0x0545, KEY_POWER },
|
||||
{ 0x0052, KEY_UP }, /* up */
|
||||
{ 0x0051, KEY_DOWN }, /* down */
|
||||
{ 0x0028, KEY_ENTER },
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_msi[] = {
|
||||
0x03, 0xfc, 0x17, 0xe8, 0x45, 0x05, 0x00, /* power */
|
||||
0x03, 0xfc, 0x0d, 0xf2, 0x51, 0x00, 0x00, /* down */
|
||||
0x03, 0xfc, 0x03, 0xfc, 0x52, 0x00, 0x00, /* up */
|
||||
0x03, 0xfc, 0x1a, 0xe5, 0x1e, 0x00, 0x00, /* 1 */
|
||||
0x03, 0xfc, 0x02, 0xfd, 0x1f, 0x00, 0x00, /* 2 */
|
||||
0x03, 0xfc, 0x04, 0xfb, 0x20, 0x00, 0x00, /* 3 */
|
||||
0x03, 0xfc, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */
|
||||
0x03, 0xfc, 0x08, 0xf7, 0x22, 0x00, 0x00, /* 5 */
|
||||
0x03, 0xfc, 0x1d, 0xe2, 0x23, 0x00, 0x00, /* 6 */
|
||||
0x03, 0xfc, 0x11, 0xee, 0x24, 0x00, 0x00, /* 7 */
|
||||
0x03, 0xfc, 0x0b, 0xf4, 0x25, 0x00, 0x00, /* 8 */
|
||||
0x03, 0xfc, 0x10, 0xef, 0x26, 0x00, 0x00, /* 9 */
|
||||
0x03, 0xfc, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */
|
||||
0x03, 0xfc, 0x14, 0xeb, 0x43, 0x00, 0x00, /* volume up */
|
||||
0x03, 0xfc, 0x1f, 0xe0, 0x42, 0x00, 0x00, /* volume down */
|
||||
0x03, 0xfc, 0x15, 0xea, 0x0f, 0x03, 0x00, /* channel up */
|
||||
0x03, 0xfc, 0x05, 0xfa, 0x0e, 0x03, 0x00, /* channel down */
|
||||
0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* enter */
|
||||
};
|
||||
|
||||
/* MYGICTV U718 */
|
||||
static struct ir_scancode ir_codes_af9015_table_mygictv[] = {
|
||||
{ 0x003d, KEY_SWITCHVIDEOMODE },
|
||||
/* TV / AV */
|
||||
{ 0x0545, KEY_POWER },
|
||||
{ 0x001e, KEY_1 },
|
||||
{ 0x001f, KEY_2 },
|
||||
{ 0x0020, KEY_3 },
|
||||
{ 0x0021, KEY_4 },
|
||||
{ 0x0022, KEY_5 },
|
||||
{ 0x0023, KEY_6 },
|
||||
{ 0x0024, KEY_7 },
|
||||
{ 0x0025, KEY_8 },
|
||||
{ 0x0026, KEY_9 },
|
||||
{ 0x0027, KEY_0 },
|
||||
{ 0x0041, KEY_MUTE },
|
||||
{ 0x002a, KEY_ESC }, /* Esc */
|
||||
{ 0x002e, KEY_CHANNELUP },
|
||||
{ 0x002d, KEY_CHANNELDOWN },
|
||||
{ 0x0042, KEY_VOLUMEDOWN },
|
||||
{ 0x0043, KEY_VOLUMEUP },
|
||||
{ 0x0052, KEY_UP }, /* up arrow */
|
||||
{ 0x0051, KEY_DOWN }, /* down arrow */
|
||||
{ 0x004f, KEY_RIGHT }, /* right arrow */
|
||||
{ 0x0050, KEY_LEFT }, /* left arrow */
|
||||
{ 0x0028, KEY_ENTER }, /* ok */
|
||||
{ 0x0115, KEY_RECORD },
|
||||
{ 0x0313, KEY_PLAY },
|
||||
{ 0x0113, KEY_PAUSE },
|
||||
{ 0x0116, KEY_STOP },
|
||||
{ 0x0307, KEY_REWIND }, /* FR << */
|
||||
{ 0x0309, KEY_FASTFORWARD }, /* FF >> */
|
||||
{ 0x003b, KEY_TIME }, /* TimeShift */
|
||||
{ 0x003e, KEY_CAMERA }, /* Snapshot */
|
||||
{ 0x0316, KEY_CYCLEWINDOWS }, /* yellow, min / max */
|
||||
{ 0x0000, KEY_ZOOM }, /* 'select' (?) */
|
||||
{ 0x0316, KEY_SHUFFLE }, /* Shuffle */
|
||||
{ 0x0345, KEY_POWER },
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_mygictv[] = {
|
||||
0x02, 0xbd, 0x0c, 0xf3, 0x3d, 0x00, 0x00, /* TV / AV */
|
||||
0x02, 0xbd, 0x14, 0xeb, 0x45, 0x05, 0x00, /* power */
|
||||
0x02, 0xbd, 0x00, 0xff, 0x1e, 0x00, 0x00, /* 1 */
|
||||
0x02, 0xbd, 0x01, 0xfe, 0x1f, 0x00, 0x00, /* 2 */
|
||||
0x02, 0xbd, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */
|
||||
0x02, 0xbd, 0x03, 0xfc, 0x21, 0x00, 0x00, /* 4 */
|
||||
0x02, 0xbd, 0x04, 0xfb, 0x22, 0x00, 0x00, /* 5 */
|
||||
0x02, 0xbd, 0x05, 0xfa, 0x23, 0x00, 0x00, /* 6 */
|
||||
0x02, 0xbd, 0x06, 0xf9, 0x24, 0x00, 0x00, /* 7 */
|
||||
0x02, 0xbd, 0x07, 0xf8, 0x25, 0x00, 0x00, /* 8 */
|
||||
0x02, 0xbd, 0x08, 0xf7, 0x26, 0x00, 0x00, /* 9 */
|
||||
0x02, 0xbd, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */
|
||||
0x02, 0xbd, 0x0a, 0xf5, 0x41, 0x00, 0x00, /* mute */
|
||||
0x02, 0xbd, 0x1c, 0xe3, 0x2a, 0x00, 0x00, /* esc */
|
||||
0x02, 0xbd, 0x1f, 0xe0, 0x43, 0x00, 0x00, /* volume up */
|
||||
0x02, 0xbd, 0x12, 0xed, 0x52, 0x00, 0x00, /* up arrow */
|
||||
0x02, 0xbd, 0x11, 0xee, 0x50, 0x00, 0x00, /* left arrow */
|
||||
0x02, 0xbd, 0x15, 0xea, 0x28, 0x00, 0x00, /* ok */
|
||||
0x02, 0xbd, 0x10, 0xef, 0x4f, 0x00, 0x00, /* right arrow */
|
||||
0x02, 0xbd, 0x13, 0xec, 0x51, 0x00, 0x00, /* down arrow */
|
||||
0x02, 0xbd, 0x0e, 0xf1, 0x42, 0x00, 0x00, /* volume down */
|
||||
0x02, 0xbd, 0x19, 0xe6, 0x15, 0x01, 0x00, /* record */
|
||||
0x02, 0xbd, 0x1e, 0xe1, 0x13, 0x03, 0x00, /* play */
|
||||
0x02, 0xbd, 0x16, 0xe9, 0x16, 0x01, 0x00, /* stop */
|
||||
0x02, 0xbd, 0x0b, 0xf4, 0x28, 0x04, 0x00, /* yellow, min / max */
|
||||
0x02, 0xbd, 0x0f, 0xf0, 0x3b, 0x00, 0x00, /* time shift */
|
||||
0x02, 0xbd, 0x18, 0xe7, 0x2e, 0x00, 0x00, /* channel up */
|
||||
0x02, 0xbd, 0x1a, 0xe5, 0x2d, 0x00, 0x00, /* channel down */
|
||||
0x02, 0xbd, 0x17, 0xe8, 0x3e, 0x00, 0x00, /* snapshot */
|
||||
0x02, 0xbd, 0x40, 0xbf, 0x13, 0x01, 0x00, /* pause */
|
||||
0x02, 0xbd, 0x41, 0xbe, 0x09, 0x03, 0x00, /* FF >> */
|
||||
0x02, 0xbd, 0x42, 0xbd, 0x07, 0x03, 0x00, /* FR << */
|
||||
0x02, 0xbd, 0x43, 0xbc, 0x00, 0x00, 0x00, /* 'select' (?) */
|
||||
0x02, 0xbd, 0x44, 0xbb, 0x16, 0x03, 0x00, /* shuffle */
|
||||
0x02, 0xbd, 0x45, 0xba, 0x45, 0x03, 0x00, /* power */
|
||||
};
|
||||
|
||||
/* KWorld PlusTV Dual DVB-T Stick (DVB-T 399U) */
|
||||
static u8 af9015_ir_table_kworld[] = {
|
||||
0x86, 0x6b, 0x0c, 0xf3, 0x2e, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x16, 0xe9, 0x2d, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x1d, 0xe2, 0x37, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x00, 0xff, 0x1e, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x01, 0xfe, 0x1f, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x02, 0xfd, 0x20, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x03, 0xfc, 0x21, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x04, 0xfb, 0x22, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x05, 0xfa, 0x23, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x06, 0xf9, 0x24, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x07, 0xf8, 0x25, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x08, 0xf7, 0x26, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x09, 0xf6, 0x4d, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x0a, 0xf5, 0x4e, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x14, 0xeb, 0x4f, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x1e, 0xe1, 0x50, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x17, 0xe8, 0x52, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x1f, 0xe0, 0x51, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x0e, 0xf1, 0x0b, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x20, 0xdf, 0x0c, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x42, 0xbd, 0x0d, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x0b, 0xf4, 0x0e, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x43, 0xbc, 0x0f, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x10, 0xef, 0x10, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x21, 0xde, 0x11, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x13, 0xec, 0x12, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x11, 0xee, 0x13, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x12, 0xed, 0x14, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x19, 0xe6, 0x15, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x1a, 0xe5, 0x16, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x1b, 0xe4, 0x17, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x4b, 0xb4, 0x18, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x40, 0xbf, 0x19, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x44, 0xbb, 0x1a, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x41, 0xbe, 0x1b, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x22, 0xdd, 0x1c, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x15, 0xea, 0x1d, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x0f, 0xf0, 0x3f, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x1c, 0xe3, 0x40, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x4a, 0xb5, 0x41, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x48, 0xb7, 0x42, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x49, 0xb6, 0x43, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x18, 0xe7, 0x44, 0x07, 0x00,
|
||||
0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00,
|
||||
};
|
||||
|
||||
/* AverMedia Volar X */
|
||||
static struct ir_scancode ir_codes_af9015_table_avermedia[] = {
|
||||
{ 0x053d, KEY_PROG1 }, /* SOURCE */
|
||||
{ 0x0512, KEY_POWER }, /* POWER */
|
||||
{ 0x051e, KEY_1 }, /* 1 */
|
||||
{ 0x051f, KEY_2 }, /* 2 */
|
||||
{ 0x0520, KEY_3 }, /* 3 */
|
||||
{ 0x0521, KEY_4 }, /* 4 */
|
||||
{ 0x0522, KEY_5 }, /* 5 */
|
||||
{ 0x0523, KEY_6 }, /* 6 */
|
||||
{ 0x0524, KEY_7 }, /* 7 */
|
||||
{ 0x0525, KEY_8 }, /* 8 */
|
||||
{ 0x0526, KEY_9 }, /* 9 */
|
||||
{ 0x053f, KEY_LEFT }, /* L / DISPLAY */
|
||||
{ 0x0527, KEY_0 }, /* 0 */
|
||||
{ 0x050f, KEY_RIGHT }, /* R / CH RTN */
|
||||
{ 0x0518, KEY_PROG2 }, /* SNAP SHOT */
|
||||
{ 0x051c, KEY_PROG3 }, /* 16-CH PREV */
|
||||
{ 0x052d, KEY_VOLUMEDOWN }, /* VOL DOWN */
|
||||
{ 0x053e, KEY_ZOOM }, /* FULL SCREEN */
|
||||
{ 0x052e, KEY_VOLUMEUP }, /* VOL UP */
|
||||
{ 0x0510, KEY_MUTE }, /* MUTE */
|
||||
{ 0x0504, KEY_AUDIO }, /* AUDIO */
|
||||
{ 0x0515, KEY_RECORD }, /* RECORD */
|
||||
{ 0x0511, KEY_PLAY }, /* PLAY */
|
||||
{ 0x0516, KEY_STOP }, /* STOP */
|
||||
{ 0x050c, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
|
||||
{ 0x0505, KEY_BACK }, /* << / RED */
|
||||
{ 0x0509, KEY_FORWARD }, /* >> / YELLOW */
|
||||
{ 0x0517, KEY_TEXT }, /* TELETEXT */
|
||||
{ 0x050a, KEY_EPG }, /* EPG */
|
||||
{ 0x0513, KEY_MENU }, /* MENU */
|
||||
|
||||
{ 0x050e, KEY_CHANNELUP }, /* CH UP */
|
||||
{ 0x050d, KEY_CHANNELDOWN }, /* CH DOWN */
|
||||
{ 0x0519, KEY_FIRST }, /* |<< / GREEN */
|
||||
{ 0x0508, KEY_LAST }, /* >>| / BLUE */
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_avermedia[] = {
|
||||
0x02, 0xfd, 0x00, 0xff, 0x12, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x01, 0xfe, 0x3d, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x03, 0xfc, 0x17, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x04, 0xfb, 0x0a, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x05, 0xfa, 0x1e, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x06, 0xf9, 0x1f, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x07, 0xf8, 0x20, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x09, 0xf6, 0x21, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x0a, 0xf5, 0x22, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x0b, 0xf4, 0x23, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x0d, 0xf2, 0x24, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x0e, 0xf1, 0x25, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x0f, 0xf0, 0x26, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x11, 0xee, 0x27, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x08, 0xf7, 0x04, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x0c, 0xf3, 0x3e, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x10, 0xef, 0x1c, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x12, 0xed, 0x3f, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x13, 0xec, 0x0f, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x14, 0xeb, 0x10, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x15, 0xea, 0x13, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x17, 0xe8, 0x18, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x18, 0xe7, 0x11, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x19, 0xe6, 0x15, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x1a, 0xe5, 0x0c, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x1b, 0xe4, 0x16, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x1c, 0xe3, 0x09, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x1d, 0xe2, 0x05, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x1e, 0xe1, 0x2d, 0x05, 0x00,
|
||||
0x02, 0xfd, 0x1f, 0xe0, 0x2e, 0x05, 0x00,
|
||||
0x03, 0xfc, 0x00, 0xff, 0x08, 0x05, 0x00,
|
||||
0x03, 0xfc, 0x01, 0xfe, 0x19, 0x05, 0x00,
|
||||
0x03, 0xfc, 0x02, 0xfd, 0x0d, 0x05, 0x00,
|
||||
0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00,
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_avermedia_ks[] = {
|
||||
0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00,
|
||||
0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00
|
||||
};
|
||||
|
||||
/* Digittrade DVB-T USB Stick */
|
||||
static struct ir_scancode ir_codes_af9015_table_digittrade[] = {
|
||||
{ 0x010f, KEY_LAST }, /* RETURN */
|
||||
{ 0x0517, KEY_TEXT }, /* TELETEXT */
|
||||
{ 0x0108, KEY_EPG }, /* EPG */
|
||||
{ 0x0513, KEY_POWER }, /* POWER */
|
||||
{ 0x0109, KEY_ZOOM }, /* FULLSCREEN */
|
||||
{ 0x0040, KEY_AUDIO }, /* DUAL SOUND */
|
||||
{ 0x002c, KEY_PRINT }, /* SNAPSHOT */
|
||||
{ 0x0516, KEY_SUBTITLE }, /* SUBTITLE */
|
||||
{ 0x0052, KEY_CHANNELUP }, /* CH Up */
|
||||
{ 0x0051, KEY_CHANNELDOWN },/* Ch Dn */
|
||||
{ 0x0057, KEY_VOLUMEUP }, /* Vol Up */
|
||||
{ 0x0056, KEY_VOLUMEDOWN }, /* Vol Dn */
|
||||
{ 0x0110, KEY_MUTE }, /* MUTE */
|
||||
{ 0x0027, KEY_0 },
|
||||
{ 0x001e, KEY_1 },
|
||||
{ 0x001f, KEY_2 },
|
||||
{ 0x0020, KEY_3 },
|
||||
{ 0x0021, KEY_4 },
|
||||
{ 0x0022, KEY_5 },
|
||||
{ 0x0023, KEY_6 },
|
||||
{ 0x0024, KEY_7 },
|
||||
{ 0x0025, KEY_8 },
|
||||
{ 0x0026, KEY_9 },
|
||||
{ 0x0117, KEY_PLAYPAUSE }, /* TIMESHIFT */
|
||||
{ 0x0115, KEY_RECORD }, /* RECORD */
|
||||
{ 0x0313, KEY_PLAY }, /* PLAY */
|
||||
{ 0x0116, KEY_STOP }, /* STOP */
|
||||
{ 0x0113, KEY_PAUSE }, /* PAUSE */
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_digittrade[] = {
|
||||
0x00, 0xff, 0x06, 0xf9, 0x13, 0x05, 0x00,
|
||||
0x00, 0xff, 0x4d, 0xb2, 0x17, 0x01, 0x00,
|
||||
0x00, 0xff, 0x1f, 0xe0, 0x2c, 0x00, 0x00,
|
||||
0x00, 0xff, 0x0a, 0xf5, 0x15, 0x01, 0x00,
|
||||
0x00, 0xff, 0x0e, 0xf1, 0x16, 0x01, 0x00,
|
||||
0x00, 0xff, 0x09, 0xf6, 0x09, 0x01, 0x00,
|
||||
0x00, 0xff, 0x01, 0xfe, 0x08, 0x01, 0x00,
|
||||
0x00, 0xff, 0x05, 0xfa, 0x10, 0x01, 0x00,
|
||||
0x00, 0xff, 0x02, 0xfd, 0x56, 0x00, 0x00,
|
||||
0x00, 0xff, 0x40, 0xbf, 0x57, 0x00, 0x00,
|
||||
0x00, 0xff, 0x19, 0xe6, 0x52, 0x00, 0x00,
|
||||
0x00, 0xff, 0x17, 0xe8, 0x51, 0x00, 0x00,
|
||||
0x00, 0xff, 0x10, 0xef, 0x0f, 0x01, 0x00,
|
||||
0x00, 0xff, 0x54, 0xab, 0x27, 0x00, 0x00,
|
||||
0x00, 0xff, 0x1b, 0xe4, 0x1e, 0x00, 0x00,
|
||||
0x00, 0xff, 0x11, 0xee, 0x1f, 0x00, 0x00,
|
||||
0x00, 0xff, 0x15, 0xea, 0x20, 0x00, 0x00,
|
||||
0x00, 0xff, 0x12, 0xed, 0x21, 0x00, 0x00,
|
||||
0x00, 0xff, 0x16, 0xe9, 0x22, 0x00, 0x00,
|
||||
0x00, 0xff, 0x4c, 0xb3, 0x23, 0x00, 0x00,
|
||||
0x00, 0xff, 0x48, 0xb7, 0x24, 0x00, 0x00,
|
||||
0x00, 0xff, 0x04, 0xfb, 0x25, 0x00, 0x00,
|
||||
0x00, 0xff, 0x00, 0xff, 0x26, 0x00, 0x00,
|
||||
0x00, 0xff, 0x1e, 0xe1, 0x13, 0x03, 0x00,
|
||||
0x00, 0xff, 0x1a, 0xe5, 0x13, 0x01, 0x00,
|
||||
0x00, 0xff, 0x03, 0xfc, 0x17, 0x05, 0x00,
|
||||
0x00, 0xff, 0x0d, 0xf2, 0x16, 0x05, 0x00,
|
||||
0x00, 0xff, 0x1d, 0xe2, 0x40, 0x00, 0x00,
|
||||
};
|
||||
|
||||
/* TREKSTOR DVB-T USB Stick */
|
||||
static struct ir_scancode ir_codes_af9015_table_trekstor[] = {
|
||||
{ 0x0704, KEY_AGAIN }, /* Home */
|
||||
{ 0x0705, KEY_MUTE }, /* Mute */
|
||||
{ 0x0706, KEY_UP }, /* Up */
|
||||
{ 0x0707, KEY_DOWN }, /* Down */
|
||||
{ 0x0709, KEY_RIGHT }, /* Right */
|
||||
{ 0x070a, KEY_ENTER }, /* OK */
|
||||
{ 0x070b, KEY_FASTFORWARD }, /* Fast forward */
|
||||
{ 0x070c, KEY_REWIND }, /* Rewind */
|
||||
{ 0x070d, KEY_PLAY }, /* Play/Pause */
|
||||
{ 0x070e, KEY_VOLUMEUP }, /* Volume + */
|
||||
{ 0x070f, KEY_VOLUMEDOWN }, /* Volume - */
|
||||
{ 0x0710, KEY_RECORD }, /* Record */
|
||||
{ 0x0711, KEY_STOP }, /* Stop */
|
||||
{ 0x0712, KEY_ZOOM }, /* TV */
|
||||
{ 0x0713, KEY_EPG }, /* Info/EPG */
|
||||
{ 0x0714, KEY_CHANNELDOWN }, /* Channel - */
|
||||
{ 0x0715, KEY_CHANNELUP }, /* Channel + */
|
||||
{ 0x071e, KEY_1 },
|
||||
{ 0x071f, KEY_2 },
|
||||
{ 0x0720, KEY_3 },
|
||||
{ 0x0721, KEY_4 },
|
||||
{ 0x0722, KEY_5 },
|
||||
{ 0x0723, KEY_6 },
|
||||
{ 0x0724, KEY_7 },
|
||||
{ 0x0725, KEY_8 },
|
||||
{ 0x0726, KEY_9 },
|
||||
{ 0x0708, KEY_LEFT }, /* LEFT */
|
||||
{ 0x0727, KEY_0 },
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_trekstor[] = {
|
||||
0x00, 0xff, 0x86, 0x79, 0x04, 0x07, 0x00,
|
||||
0x00, 0xff, 0x85, 0x7a, 0x05, 0x07, 0x00,
|
||||
0x00, 0xff, 0x87, 0x78, 0x06, 0x07, 0x00,
|
||||
0x00, 0xff, 0x8c, 0x73, 0x07, 0x07, 0x00,
|
||||
0x00, 0xff, 0x89, 0x76, 0x09, 0x07, 0x00,
|
||||
0x00, 0xff, 0x88, 0x77, 0x0a, 0x07, 0x00,
|
||||
0x00, 0xff, 0x8a, 0x75, 0x0b, 0x07, 0x00,
|
||||
0x00, 0xff, 0x9e, 0x61, 0x0c, 0x07, 0x00,
|
||||
0x00, 0xff, 0x8d, 0x72, 0x0d, 0x07, 0x00,
|
||||
0x00, 0xff, 0x8b, 0x74, 0x0e, 0x07, 0x00,
|
||||
0x00, 0xff, 0x9b, 0x64, 0x0f, 0x07, 0x00,
|
||||
0x00, 0xff, 0x9d, 0x62, 0x10, 0x07, 0x00,
|
||||
0x00, 0xff, 0x8e, 0x71, 0x11, 0x07, 0x00,
|
||||
0x00, 0xff, 0x9c, 0x63, 0x12, 0x07, 0x00,
|
||||
0x00, 0xff, 0x8f, 0x70, 0x13, 0x07, 0x00,
|
||||
0x00, 0xff, 0x93, 0x6c, 0x14, 0x07, 0x00,
|
||||
0x00, 0xff, 0x97, 0x68, 0x15, 0x07, 0x00,
|
||||
0x00, 0xff, 0x92, 0x6d, 0x1e, 0x07, 0x00,
|
||||
0x00, 0xff, 0x96, 0x69, 0x1f, 0x07, 0x00,
|
||||
0x00, 0xff, 0x9a, 0x65, 0x20, 0x07, 0x00,
|
||||
0x00, 0xff, 0x91, 0x6e, 0x21, 0x07, 0x00,
|
||||
0x00, 0xff, 0x95, 0x6a, 0x22, 0x07, 0x00,
|
||||
0x00, 0xff, 0x99, 0x66, 0x23, 0x07, 0x00,
|
||||
0x00, 0xff, 0x90, 0x6f, 0x24, 0x07, 0x00,
|
||||
0x00, 0xff, 0x94, 0x6b, 0x25, 0x07, 0x00,
|
||||
0x00, 0xff, 0x98, 0x67, 0x26, 0x07, 0x00,
|
||||
0x00, 0xff, 0x9f, 0x60, 0x08, 0x07, 0x00,
|
||||
0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00,
|
||||
};
|
||||
|
||||
/* MSI DIGIVOX mini III */
|
||||
static struct ir_scancode ir_codes_af9015_table_msi_digivox_iii[] = {
|
||||
{ 0x0713, KEY_POWER }, /* [red power button] */
|
||||
{ 0x073b, KEY_VIDEO }, /* Source */
|
||||
{ 0x073e, KEY_ZOOM }, /* Zoom */
|
||||
{ 0x070b, KEY_POWER2 }, /* ShutDown */
|
||||
{ 0x071e, KEY_1 },
|
||||
{ 0x071f, KEY_2 },
|
||||
{ 0x0720, KEY_3 },
|
||||
{ 0x0721, KEY_4 },
|
||||
{ 0x0722, KEY_5 },
|
||||
{ 0x0723, KEY_6 },
|
||||
{ 0x0724, KEY_7 },
|
||||
{ 0x0725, KEY_8 },
|
||||
{ 0x0726, KEY_9 },
|
||||
{ 0x0727, KEY_0 },
|
||||
{ 0x0752, KEY_CHANNELUP }, /* CH+ */
|
||||
{ 0x0751, KEY_CHANNELDOWN }, /* CH- */
|
||||
{ 0x0750, KEY_VOLUMEUP }, /* Vol+ */
|
||||
{ 0x074f, KEY_VOLUMEDOWN }, /* Vol- */
|
||||
{ 0x0705, KEY_ESC }, /* [back up arrow] */
|
||||
{ 0x0708, KEY_OK }, /* [enter arrow] */
|
||||
{ 0x073f, KEY_RECORD }, /* Rec */
|
||||
{ 0x0716, KEY_STOP }, /* Stop */
|
||||
{ 0x072a, KEY_PLAY }, /* Play */
|
||||
{ 0x073c, KEY_MUTE }, /* Mute */
|
||||
{ 0x0718, KEY_UP },
|
||||
{ 0x0707, KEY_DOWN },
|
||||
{ 0x070f, KEY_LEFT },
|
||||
{ 0x0715, KEY_RIGHT },
|
||||
{ 0x0736, KEY_RED },
|
||||
{ 0x0737, KEY_GREEN },
|
||||
{ 0x072d, KEY_YELLOW },
|
||||
{ 0x072e, KEY_BLUE },
|
||||
};
|
||||
|
||||
static u8 af9015_ir_table_msi_digivox_iii[] = {
|
||||
0x61, 0xd6, 0x43, 0xbc, 0x13, 0x07, 0x00, /* KEY_POWER */
|
||||
0x61, 0xd6, 0x01, 0xfe, 0x3b, 0x07, 0x00, /* KEY_VIDEO */
|
||||
0x61, 0xd6, 0x0b, 0xf4, 0x3e, 0x07, 0x00, /* KEY_ZOOM */
|
||||
0x61, 0xd6, 0x03, 0xfc, 0x0b, 0x07, 0x00, /* KEY_POWER2 */
|
||||
0x61, 0xd6, 0x04, 0xfb, 0x1e, 0x07, 0x00, /* KEY_1 */
|
||||
0x61, 0xd6, 0x08, 0xf7, 0x1f, 0x07, 0x00, /* KEY_2 */
|
||||
0x61, 0xd6, 0x02, 0xfd, 0x20, 0x07, 0x00, /* KEY_3 */
|
||||
0x61, 0xd6, 0x0f, 0xf0, 0x21, 0x07, 0x00, /* KEY_4 */
|
||||
0x61, 0xd6, 0x05, 0xfa, 0x22, 0x07, 0x00, /* KEY_5 */
|
||||
0x61, 0xd6, 0x06, 0xf9, 0x23, 0x07, 0x00, /* KEY_6 */
|
||||
0x61, 0xd6, 0x0c, 0xf3, 0x24, 0x07, 0x00, /* KEY_7 */
|
||||
0x61, 0xd6, 0x0d, 0xf2, 0x25, 0x07, 0x00, /* KEY_8 */
|
||||
0x61, 0xd6, 0x0a, 0xf5, 0x26, 0x07, 0x00, /* KEY_9 */
|
||||
0x61, 0xd6, 0x11, 0xee, 0x27, 0x07, 0x00, /* KEY_0 */
|
||||
0x61, 0xd6, 0x09, 0xf6, 0x52, 0x07, 0x00, /* KEY_CHANNELUP */
|
||||
0x61, 0xd6, 0x07, 0xf8, 0x51, 0x07, 0x00, /* KEY_CHANNELDOWN */
|
||||
0x61, 0xd6, 0x0e, 0xf1, 0x50, 0x07, 0x00, /* KEY_VOLUMEUP */
|
||||
0x61, 0xd6, 0x13, 0xec, 0x4f, 0x07, 0x00, /* KEY_VOLUMEDOWN */
|
||||
0x61, 0xd6, 0x10, 0xef, 0x05, 0x07, 0x00, /* KEY_ESC */
|
||||
0x61, 0xd6, 0x12, 0xed, 0x08, 0x07, 0x00, /* KEY_OK */
|
||||
0x61, 0xd6, 0x14, 0xeb, 0x3f, 0x07, 0x00, /* KEY_RECORD */
|
||||
0x61, 0xd6, 0x15, 0xea, 0x16, 0x07, 0x00, /* KEY_STOP */
|
||||
0x61, 0xd6, 0x16, 0xe9, 0x2a, 0x07, 0x00, /* KEY_PLAY */
|
||||
0x61, 0xd6, 0x17, 0xe8, 0x3c, 0x07, 0x00, /* KEY_MUTE */
|
||||
0x61, 0xd6, 0x18, 0xe7, 0x18, 0x07, 0x00, /* KEY_UP */
|
||||
0x61, 0xd6, 0x19, 0xe6, 0x07, 0x07, 0x00, /* KEY_DOWN */
|
||||
0x61, 0xd6, 0x1a, 0xe5, 0x0f, 0x07, 0x00, /* KEY_LEFT */
|
||||
0x61, 0xd6, 0x1b, 0xe4, 0x15, 0x07, 0x00, /* KEY_RIGHT */
|
||||
0x61, 0xd6, 0x1c, 0xe3, 0x36, 0x07, 0x00, /* KEY_RED */
|
||||
0x61, 0xd6, 0x1d, 0xe2, 0x37, 0x07, 0x00, /* KEY_GREEN */
|
||||
0x61, 0xd6, 0x1e, 0xe1, 0x2d, 0x07, 0x00, /* KEY_YELLOW */
|
||||
0x61, 0xd6, 0x1f, 0xe0, 0x2e, 0x07, 0x00, /* KEY_BLUE */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct anysee_state *state = adap->dev->priv;
|
||||
deb_info("%s: \n", __func__);
|
||||
deb_info("%s:\n", __func__);
|
||||
|
||||
switch (state->tuner) {
|
||||
case DVB_PLL_THOMSON_DTT7579:
|
||||
|
|
@ -374,78 +374,32 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
||||
static int anysee_rc_query(struct dvb_usb_device *d)
|
||||
{
|
||||
u8 buf[] = {CMD_GET_IR_CODE};
|
||||
struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
|
||||
u8 ircode[2];
|
||||
int i, ret;
|
||||
int ret;
|
||||
|
||||
ret = anysee_ctrl_msg(d, buf, sizeof(buf), &ircode[0], 2);
|
||||
/* Remote controller is basic NEC using address byte 0x08.
|
||||
Anysee device RC query returns only two bytes, status and code,
|
||||
address byte is dropped. Also it does not return any value for
|
||||
NEC RCs having address byte other than 0x08. Due to that, we
|
||||
cannot use that device as standard NEC receiver.
|
||||
It could be possible make hack which reads whole code directly
|
||||
from device memory... */
|
||||
|
||||
ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*event = 0;
|
||||
*state = REMOTE_NO_KEY_PRESSED;
|
||||
|
||||
for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
|
||||
if (rc5_custom(&keymap[i]) == ircode[0] &&
|
||||
rc5_data(&keymap[i]) == ircode[1]) {
|
||||
*event = keymap[i].keycode;
|
||||
*state = REMOTE_KEY_PRESSED;
|
||||
return 0;
|
||||
}
|
||||
if (ircode[0]) {
|
||||
deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
|
||||
ir_keydown(d->rc_input_dev, 0x08 << 8 | ircode[1], 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ir_scancode ir_codes_anysee_table[] = {
|
||||
{ 0x0100, KEY_0 },
|
||||
{ 0x0101, KEY_1 },
|
||||
{ 0x0102, KEY_2 },
|
||||
{ 0x0103, KEY_3 },
|
||||
{ 0x0104, KEY_4 },
|
||||
{ 0x0105, KEY_5 },
|
||||
{ 0x0106, KEY_6 },
|
||||
{ 0x0107, KEY_7 },
|
||||
{ 0x0108, KEY_8 },
|
||||
{ 0x0109, KEY_9 },
|
||||
{ 0x010a, KEY_POWER },
|
||||
{ 0x010b, KEY_DOCUMENTS }, /* * */
|
||||
{ 0x0119, KEY_FAVORITES },
|
||||
{ 0x0120, KEY_SLEEP },
|
||||
{ 0x0121, KEY_MODE }, /* 4:3 / 16:9 select */
|
||||
{ 0x0122, KEY_ZOOM },
|
||||
{ 0x0147, KEY_TEXT },
|
||||
{ 0x0116, KEY_TV }, /* TV / radio select */
|
||||
{ 0x011e, KEY_LANGUAGE }, /* Second Audio Program */
|
||||
{ 0x011a, KEY_SUBTITLE },
|
||||
{ 0x011b, KEY_CAMERA }, /* screenshot */
|
||||
{ 0x0142, KEY_MUTE },
|
||||
{ 0x010e, KEY_MENU },
|
||||
{ 0x010f, KEY_EPG },
|
||||
{ 0x0117, KEY_INFO },
|
||||
{ 0x0110, KEY_EXIT },
|
||||
{ 0x0113, KEY_VOLUMEUP },
|
||||
{ 0x0112, KEY_VOLUMEDOWN },
|
||||
{ 0x0111, KEY_CHANNELUP },
|
||||
{ 0x0114, KEY_CHANNELDOWN },
|
||||
{ 0x0115, KEY_OK },
|
||||
{ 0x011d, KEY_RED },
|
||||
{ 0x011f, KEY_GREEN },
|
||||
{ 0x011c, KEY_YELLOW },
|
||||
{ 0x0144, KEY_BLUE },
|
||||
{ 0x010c, KEY_SHUFFLE }, /* snapshot */
|
||||
{ 0x0148, KEY_STOP },
|
||||
{ 0x0150, KEY_PLAY },
|
||||
{ 0x0151, KEY_PAUSE },
|
||||
{ 0x0149, KEY_RECORD },
|
||||
{ 0x0118, KEY_PREVIOUS }, /* |<< */
|
||||
{ 0x010d, KEY_NEXT }, /* >>| */
|
||||
{ 0x0124, KEY_PROG1 }, /* F1 */
|
||||
{ 0x0125, KEY_PROG2 }, /* F2 */
|
||||
};
|
||||
|
||||
/* DVB USB Driver stuff */
|
||||
static struct dvb_usb_device_properties anysee_properties;
|
||||
|
||||
|
|
@ -520,11 +474,12 @@ static struct dvb_usb_device_properties anysee_properties = {
|
|||
}
|
||||
},
|
||||
|
||||
.rc.legacy = {
|
||||
.rc_key_map = ir_codes_anysee_table,
|
||||
.rc_key_map_size = ARRAY_SIZE(ir_codes_anysee_table),
|
||||
.rc.core = {
|
||||
.rc_codes = RC_MAP_ANYSEE,
|
||||
.protocol = IR_TYPE_OTHER,
|
||||
.module_name = "anysee",
|
||||
.rc_query = anysee_rc_query,
|
||||
.rc_interval = 200, /* windows driver uses 500ms */
|
||||
.rc_interval = 250, /* windows driver uses 500ms */
|
||||
},
|
||||
|
||||
.i2c_algo = &anysee_i2c_algo,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
|
|||
}
|
||||
|
||||
strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
|
||||
d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
|
||||
d->i2c_adap.algo = d->props.i2c_algo;
|
||||
d->i2c_adap.algo_data = NULL;
|
||||
d->i2c_adap.dev.parent = &d->udev->dev;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#define USB_VID_EMPIA 0xeb1a
|
||||
#define USB_VID_GENPIX 0x09c0
|
||||
#define USB_VID_GRANDTEC 0x5032
|
||||
#define USB_VID_GTEK 0x1f4d
|
||||
#define USB_VID_HANFTEK 0x15f4
|
||||
#define USB_VID_HAUPPAUGE 0x2040
|
||||
#define USB_VID_HYPER_PALTEK 0x1025
|
||||
|
|
@ -133,6 +134,8 @@
|
|||
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
|
||||
#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
|
||||
#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069
|
||||
#define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097
|
||||
#define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC 0x0099
|
||||
#define USB_PID_TWINHAN_VP7041_COLD 0x3201
|
||||
#define USB_PID_TWINHAN_VP7041_WARM 0x3202
|
||||
#define USB_PID_TWINHAN_VP7020_COLD 0x3203
|
||||
|
|
@ -143,6 +146,7 @@
|
|||
#define USB_PID_TWINHAN_VP7021_WARM 0x3208
|
||||
#define USB_PID_TINYTWIN 0x3226
|
||||
#define USB_PID_TINYTWIN_2 0xe402
|
||||
#define USB_PID_TINYTWIN_3 0x9016
|
||||
#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
|
||||
#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
|
||||
#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
|
||||
|
|
@ -196,6 +200,7 @@
|
|||
#define USB_PID_AVERMEDIA_A309 0xa309
|
||||
#define USB_PID_AVERMEDIA_A310 0xa310
|
||||
#define USB_PID_AVERMEDIA_A850 0x850a
|
||||
#define USB_PID_AVERMEDIA_A850T 0x850b
|
||||
#define USB_PID_AVERMEDIA_A805 0xa805
|
||||
#define USB_PID_AVERMEDIA_A815M 0x815a
|
||||
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
|
||||
|
|
@ -268,6 +273,7 @@
|
|||
#define USB_PID_GENPIX_8PSK_REV_2 0x0202
|
||||
#define USB_PID_GENPIX_SKYWALKER_1 0x0203
|
||||
#define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204
|
||||
#define USB_PID_GENPIX_SKYWALKER_2 0x0206
|
||||
#define USB_PID_SIGMATEK_DVB_110 0x6610
|
||||
#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
|
||||
#define USB_PID_MSI_DIGIVOX_DUO 0x8801
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _jdvbt90502_write(struct dvb_frontend *fe, u8 *buf, int len)
|
||||
static int _jdvbt90502_write(struct dvb_frontend *fe, const u8 buf[], int len)
|
||||
{
|
||||
struct jdvbt90502_state *state = fe->demodulator_priv;
|
||||
int err, i;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength
|
|||
|
||||
static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
|
||||
{
|
||||
tune->min_delay_ms = 200;
|
||||
tune->min_delay_ms = 800;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -334,7 +334,7 @@ success:
|
|||
|
||||
static struct dvb_frontend_ops gp8psk_fe_ops = {
|
||||
.info = {
|
||||
.name = "Genpix 8psk-to-USB2 DVB-S",
|
||||
.name = "Genpix DVB-S",
|
||||
.type = FE_QPSK,
|
||||
.frequency_min = 800000,
|
||||
.frequency_max = 2250000,
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ static struct usb_device_id gp8psk_usb_table [] = {
|
|||
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
|
||||
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
|
||||
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
|
||||
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_2) },
|
||||
/* { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */
|
||||
{ 0 },
|
||||
};
|
||||
|
|
@ -258,7 +259,7 @@ static struct dvb_usb_device_properties gp8psk_properties = {
|
|||
|
||||
.generic_bulk_ctrl_endpoint = 0x01,
|
||||
|
||||
.num_device_descs = 3,
|
||||
.num_device_descs = 4,
|
||||
.devices = {
|
||||
{ .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
|
||||
.cold_ids = { &gp8psk_usb_table[0], NULL },
|
||||
|
|
@ -272,6 +273,10 @@ static struct dvb_usb_device_properties gp8psk_properties = {
|
|||
.cold_ids = { NULL },
|
||||
.warm_ids = { &gp8psk_usb_table[3], NULL },
|
||||
},
|
||||
{ .name = "Genpix SkyWalker-2 DVB-S receiver",
|
||||
.cold_ids = { NULL },
|
||||
.warm_ids = { &gp8psk_usb_table[4], NULL },
|
||||
},
|
||||
{ NULL },
|
||||
}
|
||||
};
|
||||
|
|
@ -306,6 +311,6 @@ module_init(gp8psk_usb_module_init);
|
|||
module_exit(gp8psk_usb_module_exit);
|
||||
|
||||
MODULE_AUTHOR("Alan Nisota <[email protected]>");
|
||||
MODULE_DESCRIPTION("Driver for Genpix 8psk-to-USB2 DVB-S");
|
||||
MODULE_DESCRIPTION("Driver for Genpix DVB-S");
|
||||
MODULE_VERSION("1.1");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
1088
drivers/media/dvb/dvb-usb/lmedm04.c
Normal file
1088
drivers/media/dvb/dvb-usb/lmedm04.c
Normal file
File diff suppressed because it is too large
Load diff
173
drivers/media/dvb/dvb-usb/lmedm04.h
Normal file
173
drivers/media/dvb/dvb-usb/lmedm04.h
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/* DVB USB compliant linux driver for
|
||||
*
|
||||
* DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
|
||||
* LME2510C + LG TDQY-P001F
|
||||
* LME2510 + LG TDQY-P001F
|
||||
*
|
||||
* MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
|
||||
* SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
|
||||
*
|
||||
* MVB001F (LME2510+LGTDQT-P001F)
|
||||
* LG TDQY - P001F =(TDA8263 + TDA10086H)
|
||||
*
|
||||
* MVB0001F (LME2510C+LGTDQT-P001F)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 2.
|
||||
* *
|
||||
* see Documentation/dvb/README.dvb-usb for more information
|
||||
*/
|
||||
#ifndef _DVB_USB_LME2510_H_
|
||||
#define _DVB_USB_LME2510_H_
|
||||
|
||||
/* Streamer & PID
|
||||
*
|
||||
* Note: These commands do not actually stop the streaming
|
||||
* but form some kind of packet filtering/stream count
|
||||
* or tuning related functions.
|
||||
* 06 XX
|
||||
* offset 1 = 00 Enable Streaming
|
||||
*
|
||||
*
|
||||
* PID
|
||||
* 03 XX XX ----> reg number ---> setting....20 XX
|
||||
* offset 1 = length
|
||||
* offset 2 = start of data
|
||||
* end byte -1 = 20
|
||||
* end byte = clear pid always a0, other wise 9c, 9a ??
|
||||
*
|
||||
*/
|
||||
#define LME_ST_ON_W {0x06, 0x00}
|
||||
#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0}
|
||||
|
||||
/* LNB Voltage
|
||||
* 07 XX XX
|
||||
* offset 1 = 01
|
||||
* offset 2 = 00=Voltage low 01=Voltage high
|
||||
*
|
||||
* LNB Power
|
||||
* 03 01 XX
|
||||
* offset 2 = 00=ON 01=OFF
|
||||
*/
|
||||
|
||||
#define LME_VOLTAGE_L {0x07, 0x01, 0x00}
|
||||
#define LME_VOLTAGE_H {0x07, 0x01, 0x01}
|
||||
#define LNB_ON {0x3a, 0x01, 0x00}
|
||||
#define LNB_OFF {0x3a, 0x01, 0x01}
|
||||
|
||||
/* Initial stv0288 settings for 7395 Frontend */
|
||||
static u8 s7395_inittab[] = {
|
||||
0x01, 0x15,
|
||||
0x02, 0x20,
|
||||
0x03, 0xa0,
|
||||
0x04, 0xa0,
|
||||
0x05, 0x12,
|
||||
0x06, 0x00,
|
||||
0x09, 0x00,
|
||||
0x0a, 0x04,
|
||||
0x0b, 0x00,
|
||||
0x0c, 0x00,
|
||||
0x0d, 0x00,
|
||||
0x0e, 0xc1,
|
||||
0x0f, 0x54,
|
||||
0x11, 0x7a,
|
||||
0x12, 0x03,
|
||||
0x13, 0x48,
|
||||
0x14, 0x84,
|
||||
0x15, 0xc5,
|
||||
0x16, 0xb8,
|
||||
0x17, 0x9c,
|
||||
0x18, 0x00,
|
||||
0x19, 0xa6,
|
||||
0x1a, 0x88,
|
||||
0x1b, 0x8f,
|
||||
0x1c, 0xf0,
|
||||
0x20, 0x0b,
|
||||
0x21, 0x54,
|
||||
0x22, 0xff,
|
||||
0x23, 0x01,
|
||||
0x28, 0x46,
|
||||
0x29, 0x66,
|
||||
0x2a, 0x90,
|
||||
0x2b, 0xfa,
|
||||
0x2c, 0xd9,
|
||||
0x30, 0x0,
|
||||
0x31, 0x1e,
|
||||
0x32, 0x14,
|
||||
0x33, 0x0f,
|
||||
0x34, 0x09,
|
||||
0x35, 0x0c,
|
||||
0x36, 0x05,
|
||||
0x37, 0x2f,
|
||||
0x38, 0x16,
|
||||
0x39, 0xbd,
|
||||
0x3a, 0x0,
|
||||
0x3b, 0x13,
|
||||
0x3c, 0x11,
|
||||
0x3d, 0x30,
|
||||
0x40, 0x63,
|
||||
0x41, 0x04,
|
||||
0x42, 0x60,
|
||||
0x43, 0x00,
|
||||
0x44, 0x00,
|
||||
0x45, 0x00,
|
||||
0x46, 0x00,
|
||||
0x47, 0x00,
|
||||
0x4a, 0x00,
|
||||
0x50, 0x12,
|
||||
0x51, 0x36,
|
||||
0x52, 0x21,
|
||||
0x53, 0x94,
|
||||
0x54, 0xb2,
|
||||
0x55, 0x29,
|
||||
0x56, 0x64,
|
||||
0x57, 0x2b,
|
||||
0x58, 0x54,
|
||||
0x59, 0x86,
|
||||
0x5a, 0x00,
|
||||
0x5b, 0x9b,
|
||||
0x5c, 0x08,
|
||||
0x5d, 0x7f,
|
||||
0x5e, 0xff,
|
||||
0x5f, 0x8d,
|
||||
0x70, 0x0,
|
||||
0x71, 0x0,
|
||||
0x72, 0x0,
|
||||
0x74, 0x0,
|
||||
0x75, 0x0,
|
||||
0x76, 0x0,
|
||||
0x81, 0x0,
|
||||
0x82, 0x3f,
|
||||
0x83, 0x3f,
|
||||
0x84, 0x0,
|
||||
0x85, 0x0,
|
||||
0x88, 0x0,
|
||||
0x89, 0x0,
|
||||
0x8a, 0x0,
|
||||
0x8b, 0x0,
|
||||
0x8c, 0x0,
|
||||
0x90, 0x0,
|
||||
0x91, 0x0,
|
||||
0x92, 0x0,
|
||||
0x93, 0x0,
|
||||
0x94, 0x1c,
|
||||
0x97, 0x0,
|
||||
0xa0, 0x48,
|
||||
0xa1, 0x0,
|
||||
0xb0, 0xb8,
|
||||
0xb1, 0x3a,
|
||||
0xb2, 0x10,
|
||||
0xb3, 0x82,
|
||||
0xb4, 0x80,
|
||||
0xb5, 0x82,
|
||||
0xb6, 0x82,
|
||||
0xb7, 0x82,
|
||||
0xb8, 0x20,
|
||||
0xb9, 0x0,
|
||||
0xf0, 0x0,
|
||||
0xf1, 0x0,
|
||||
0xf2, 0xc0,
|
||||
0xff, 0xff,
|
||||
};
|
||||
#endif
|
||||
|
|
@ -24,6 +24,8 @@
|
|||
#include <linux/wait.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <dvb_frontend.h>
|
||||
|
||||
#include "firedtv.h"
|
||||
|
||||
#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL
|
||||
|
|
@ -130,6 +132,20 @@ MODULE_PARM_DESC(debug, "Verbose logging (none = 0"
|
|||
", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS)
|
||||
", or a combination, or all = -1)");
|
||||
|
||||
/*
|
||||
* This is a workaround since there is no vendor specific command to retrieve
|
||||
* ca_info using AVC. If this parameter is not used, ca_system_id will be
|
||||
* filled with application_manufacturer from ca_app_info.
|
||||
* Digital Everywhere have said that adding ca_info is on their TODO list.
|
||||
*/
|
||||
static unsigned int num_fake_ca_system_ids;
|
||||
static int fake_ca_system_ids[4] = { -1, -1, -1, -1 };
|
||||
module_param_array(fake_ca_system_ids, int, &num_fake_ca_system_ids, 0644);
|
||||
MODULE_PARM_DESC(fake_ca_system_ids, "If your CAM application manufacturer "
|
||||
"does not have the same ca_system_id as your CAS, you can "
|
||||
"override what ca_system_ids are presented to the "
|
||||
"application by setting this field to an array of ids.");
|
||||
|
||||
static const char *debug_fcp_ctype(unsigned int ctype)
|
||||
{
|
||||
static const char *ctypes[] = {
|
||||
|
|
@ -368,10 +384,30 @@ static int avc_tuner_tuneqpsk(struct firedtv *fdtv,
|
|||
c->operand[12] = 0;
|
||||
|
||||
if (fdtv->type == FIREDTV_DVB_S2) {
|
||||
c->operand[13] = 0x1;
|
||||
c->operand[14] = 0xff;
|
||||
c->operand[15] = 0xff;
|
||||
|
||||
if (fdtv->fe.dtv_property_cache.delivery_system == SYS_DVBS2) {
|
||||
switch (fdtv->fe.dtv_property_cache.modulation) {
|
||||
case QAM_16: c->operand[13] = 0x1; break;
|
||||
case QPSK: c->operand[13] = 0x2; break;
|
||||
case PSK_8: c->operand[13] = 0x3; break;
|
||||
default: c->operand[13] = 0x2; break;
|
||||
}
|
||||
switch (fdtv->fe.dtv_property_cache.rolloff) {
|
||||
case ROLLOFF_AUTO: c->operand[14] = 0x2; break;
|
||||
case ROLLOFF_35: c->operand[14] = 0x2; break;
|
||||
case ROLLOFF_20: c->operand[14] = 0x0; break;
|
||||
case ROLLOFF_25: c->operand[14] = 0x1; break;
|
||||
/* case ROLLOFF_NONE: c->operand[14] = 0xff; break; */
|
||||
}
|
||||
switch (fdtv->fe.dtv_property_cache.pilot) {
|
||||
case PILOT_AUTO: c->operand[15] = 0x0; break;
|
||||
case PILOT_OFF: c->operand[15] = 0x0; break;
|
||||
case PILOT_ON: c->operand[15] = 0x1; break;
|
||||
}
|
||||
} else {
|
||||
c->operand[13] = 0x1; /* auto modulation */
|
||||
c->operand[14] = 0xff; /* disable rolloff */
|
||||
c->operand[15] = 0xff; /* disable pilot */
|
||||
}
|
||||
return 16;
|
||||
} else {
|
||||
return 13;
|
||||
|
|
@ -977,7 +1013,7 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
|
|||
{
|
||||
struct avc_command_frame *c = (void *)fdtv->avc_data;
|
||||
struct avc_response_frame *r = (void *)fdtv->avc_data;
|
||||
int pos, ret;
|
||||
int i, pos, ret;
|
||||
|
||||
mutex_lock(&fdtv->avc_mutex);
|
||||
|
||||
|
|
@ -1004,9 +1040,18 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
|
|||
app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff;
|
||||
app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff;
|
||||
app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff;
|
||||
app_info[3] = 2;
|
||||
app_info[4] = r->operand[pos + 0];
|
||||
app_info[5] = r->operand[pos + 1];
|
||||
if (num_fake_ca_system_ids == 0) {
|
||||
app_info[3] = 2;
|
||||
app_info[4] = r->operand[pos + 0];
|
||||
app_info[5] = r->operand[pos + 1];
|
||||
} else {
|
||||
app_info[3] = num_fake_ca_system_ids * 2;
|
||||
for (i = 0; i < num_fake_ca_system_ids; i++) {
|
||||
app_info[4 + i * 2] =
|
||||
(fake_ca_system_ids[i] >> 8) & 0xff;
|
||||
app_info[5 + i * 2] = fake_ca_system_ids[i] & 0xff;
|
||||
}
|
||||
}
|
||||
*len = app_info[3] + 4;
|
||||
out:
|
||||
mutex_unlock(&fdtv->avc_mutex);
|
||||
|
|
|
|||
|
|
@ -155,6 +155,16 @@ static int fdtv_get_frontend(struct dvb_frontend *fe,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int fdtv_get_property(struct dvb_frontend *fe, struct dtv_property *tvp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fdtv_set_property(struct dvb_frontend *fe, struct dtv_property *tvp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fdtv_frontend_init(struct firedtv *fdtv)
|
||||
{
|
||||
struct dvb_frontend_ops *ops = &fdtv->fe.ops;
|
||||
|
|
@ -166,6 +176,9 @@ void fdtv_frontend_init(struct firedtv *fdtv)
|
|||
ops->set_frontend = fdtv_set_frontend;
|
||||
ops->get_frontend = fdtv_get_frontend;
|
||||
|
||||
ops->get_property = fdtv_get_property;
|
||||
ops->set_property = fdtv_set_property;
|
||||
|
||||
ops->read_status = fdtv_read_status;
|
||||
ops->read_ber = fdtv_read_ber;
|
||||
ops->read_signal_strength = fdtv_read_signal_strength;
|
||||
|
|
@ -179,6 +192,24 @@ void fdtv_frontend_init(struct firedtv *fdtv)
|
|||
|
||||
switch (fdtv->type) {
|
||||
case FIREDTV_DVB_S:
|
||||
fi->type = FE_QPSK;
|
||||
|
||||
fi->frequency_min = 950000;
|
||||
fi->frequency_max = 2150000;
|
||||
fi->frequency_stepsize = 125;
|
||||
fi->symbol_rate_min = 1000000;
|
||||
fi->symbol_rate_max = 40000000;
|
||||
|
||||
fi->caps = FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_1_2 |
|
||||
FE_CAN_FEC_2_3 |
|
||||
FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 |
|
||||
FE_CAN_FEC_7_8 |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK;
|
||||
break;
|
||||
|
||||
case FIREDTV_DVB_S2:
|
||||
fi->type = FE_QPSK;
|
||||
|
||||
|
|
@ -188,14 +219,15 @@ void fdtv_frontend_init(struct firedtv *fdtv)
|
|||
fi->symbol_rate_min = 1000000;
|
||||
fi->symbol_rate_max = 40000000;
|
||||
|
||||
fi->caps = FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_1_2 |
|
||||
FE_CAN_FEC_2_3 |
|
||||
FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 |
|
||||
FE_CAN_FEC_7_8 |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK;
|
||||
fi->caps = FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_1_2 |
|
||||
FE_CAN_FEC_2_3 |
|
||||
FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 |
|
||||
FE_CAN_FEC_7_8 |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK |
|
||||
FE_CAN_2G_MODULATION;
|
||||
break;
|
||||
|
||||
case FIREDTV_DVB_C:
|
||||
|
|
|
|||
|
|
@ -257,6 +257,13 @@ config DVB_CX22702
|
|||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_S5H1432
|
||||
tristate "Samsung s5h1432 demodulator (OFDM)"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_DRX397XD
|
||||
tristate "Micronas DRX3975D/DRX3977D based"
|
||||
depends on DVB_CORE && I2C
|
||||
|
|
@ -455,16 +462,8 @@ config DVB_LGDT330X
|
|||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_LGDT3304
|
||||
tristate "LG Electronics LGDT3304"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_LGDT3305
|
||||
tristate "LG Electronics LGDT3305 based"
|
||||
tristate "LG Electronics LGDT3304 and LGDT3305 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
|
|
@ -607,6 +606,13 @@ config DVB_TDA665x
|
|||
Currently supported tuners:
|
||||
* Panasonic ENV57H12D5 (ET-50DT)
|
||||
|
||||
config DVB_IX2505V
|
||||
tristate "Sharp IX2505V silicon tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
comment "Tools to develop new frontends"
|
||||
|
||||
config DVB_DUMMY_FE
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ obj-$(CONFIG_DVB_STB0899) += stb0899.o
|
|||
obj-$(CONFIG_DVB_STB6100) += stb6100.o
|
||||
obj-$(CONFIG_DVB_SP8870) += sp8870.o
|
||||
obj-$(CONFIG_DVB_CX22700) += cx22700.o
|
||||
obj-$(CONFIG_DVB_S5H1432) += s5h1432.o
|
||||
obj-$(CONFIG_DVB_CX24110) += cx24110.o
|
||||
obj-$(CONFIG_DVB_TDA8083) += tda8083.o
|
||||
obj-$(CONFIG_DVB_L64781) += l64781.o
|
||||
|
|
@ -45,7 +46,6 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o
|
|||
obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
|
||||
obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
|
||||
obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
|
||||
obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o
|
||||
obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
|
||||
obj-$(CONFIG_DVB_CX24123) += cx24123.o
|
||||
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
|
||||
|
|
@ -82,3 +82,4 @@ obj-$(CONFIG_DVB_ISL6423) += isl6423.o
|
|||
obj-$(CONFIG_DVB_EC100) += ec100.o
|
||||
obj-$(CONFIG_DVB_DS3000) += ds3000.o
|
||||
obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
|
||||
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ struct af9013_state {
|
|||
|
||||
struct af9013_config config;
|
||||
|
||||
/* tuner/demod RF and IF AGC limits used for signal strength calc */
|
||||
u8 signal_strength_en, rf_50, rf_80, if_50, if_80;
|
||||
u16 signal_strength;
|
||||
u32 ber;
|
||||
u32 ucblocks;
|
||||
|
|
@ -220,184 +222,37 @@ static u32 af913_div(u32 a, u32 b, u32 x)
|
|||
|
||||
static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 i = 0;
|
||||
u8 buf[24];
|
||||
u32 uninitialized_var(ns_coeff1_2048nu);
|
||||
u32 uninitialized_var(ns_coeff1_8191nu);
|
||||
u32 uninitialized_var(ns_coeff1_8192nu);
|
||||
u32 uninitialized_var(ns_coeff1_8193nu);
|
||||
u32 uninitialized_var(ns_coeff2_2k);
|
||||
u32 uninitialized_var(ns_coeff2_8k);
|
||||
|
||||
int ret, i, j, found;
|
||||
deb_info("%s: adc_clock:%d bw:%d\n", __func__,
|
||||
state->config.adc_clock, bw);
|
||||
|
||||
switch (state->config.adc_clock) {
|
||||
case 28800: /* 28.800 MHz */
|
||||
switch (bw) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
ns_coeff1_2048nu = 0x01e79e7a;
|
||||
ns_coeff1_8191nu = 0x0079eb6e;
|
||||
ns_coeff1_8192nu = 0x0079e79e;
|
||||
ns_coeff1_8193nu = 0x0079e3cf;
|
||||
ns_coeff2_2k = 0x00f3cf3d;
|
||||
ns_coeff2_8k = 0x003cf3cf;
|
||||
/* lookup coeff from table */
|
||||
for (i = 0, found = 0; i < ARRAY_SIZE(coeff_table); i++) {
|
||||
if (coeff_table[i].adc_clock == state->config.adc_clock &&
|
||||
coeff_table[i].bw == bw) {
|
||||
found = 1;
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
ns_coeff1_2048nu = 0x0238e38e;
|
||||
ns_coeff1_8191nu = 0x008e3d55;
|
||||
ns_coeff1_8192nu = 0x008e38e4;
|
||||
ns_coeff1_8193nu = 0x008e3472;
|
||||
ns_coeff2_2k = 0x011c71c7;
|
||||
ns_coeff2_8k = 0x00471c72;
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
ns_coeff1_2048nu = 0x028a28a3;
|
||||
ns_coeff1_8191nu = 0x00a28f3d;
|
||||
ns_coeff1_8192nu = 0x00a28a29;
|
||||
ns_coeff1_8193nu = 0x00a28514;
|
||||
ns_coeff2_2k = 0x01451451;
|
||||
ns_coeff2_8k = 0x00514514;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 20480: /* 20.480 MHz */
|
||||
switch (bw) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
ns_coeff1_2048nu = 0x02adb6dc;
|
||||
ns_coeff1_8191nu = 0x00ab7313;
|
||||
ns_coeff1_8192nu = 0x00ab6db7;
|
||||
ns_coeff1_8193nu = 0x00ab685c;
|
||||
ns_coeff2_2k = 0x0156db6e;
|
||||
ns_coeff2_8k = 0x0055b6dc;
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
ns_coeff1_2048nu = 0x03200001;
|
||||
ns_coeff1_8191nu = 0x00c80640;
|
||||
ns_coeff1_8192nu = 0x00c80000;
|
||||
ns_coeff1_8193nu = 0x00c7f9c0;
|
||||
ns_coeff2_2k = 0x01900000;
|
||||
ns_coeff2_8k = 0x00640000;
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
ns_coeff1_2048nu = 0x03924926;
|
||||
ns_coeff1_8191nu = 0x00e4996e;
|
||||
ns_coeff1_8192nu = 0x00e49249;
|
||||
ns_coeff1_8193nu = 0x00e48b25;
|
||||
ns_coeff2_2k = 0x01c92493;
|
||||
ns_coeff2_8k = 0x00724925;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 28000: /* 28.000 MHz */
|
||||
switch (bw) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
ns_coeff1_2048nu = 0x01f58d10;
|
||||
ns_coeff1_8191nu = 0x007d672f;
|
||||
ns_coeff1_8192nu = 0x007d6344;
|
||||
ns_coeff1_8193nu = 0x007d5f59;
|
||||
ns_coeff2_2k = 0x00fac688;
|
||||
ns_coeff2_8k = 0x003eb1a2;
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
ns_coeff1_2048nu = 0x02492492;
|
||||
ns_coeff1_8191nu = 0x00924db7;
|
||||
ns_coeff1_8192nu = 0x00924925;
|
||||
ns_coeff1_8193nu = 0x00924492;
|
||||
ns_coeff2_2k = 0x01249249;
|
||||
ns_coeff2_8k = 0x00492492;
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
ns_coeff1_2048nu = 0x029cbc15;
|
||||
ns_coeff1_8191nu = 0x00a7343f;
|
||||
ns_coeff1_8192nu = 0x00a72f05;
|
||||
ns_coeff1_8193nu = 0x00a729cc;
|
||||
ns_coeff2_2k = 0x014e5e0a;
|
||||
ns_coeff2_8k = 0x00539783;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 25000: /* 25.000 MHz */
|
||||
switch (bw) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
ns_coeff1_2048nu = 0x0231bcb5;
|
||||
ns_coeff1_8191nu = 0x008c7391;
|
||||
ns_coeff1_8192nu = 0x008c6f2d;
|
||||
ns_coeff1_8193nu = 0x008c6aca;
|
||||
ns_coeff2_2k = 0x0118de5b;
|
||||
ns_coeff2_8k = 0x00463797;
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
ns_coeff1_2048nu = 0x028f5c29;
|
||||
ns_coeff1_8191nu = 0x00a3dc29;
|
||||
ns_coeff1_8192nu = 0x00a3d70a;
|
||||
ns_coeff1_8193nu = 0x00a3d1ec;
|
||||
ns_coeff2_2k = 0x0147ae14;
|
||||
ns_coeff2_8k = 0x0051eb85;
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
ns_coeff1_2048nu = 0x02ecfb9d;
|
||||
ns_coeff1_8191nu = 0x00bb44c1;
|
||||
ns_coeff1_8192nu = 0x00bb3ee7;
|
||||
ns_coeff1_8193nu = 0x00bb390d;
|
||||
ns_coeff2_2k = 0x01767dce;
|
||||
ns_coeff2_8k = 0x005d9f74;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err("invalid xtal");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ret) {
|
||||
err("invalid bandwidth");
|
||||
return ret;
|
||||
}
|
||||
|
||||
buf[i++] = (u8) ((ns_coeff1_2048nu & 0x03000000) >> 24);
|
||||
buf[i++] = (u8) ((ns_coeff1_2048nu & 0x00ff0000) >> 16);
|
||||
buf[i++] = (u8) ((ns_coeff1_2048nu & 0x0000ff00) >> 8);
|
||||
buf[i++] = (u8) ((ns_coeff1_2048nu & 0x000000ff));
|
||||
buf[i++] = (u8) ((ns_coeff2_2k & 0x01c00000) >> 22);
|
||||
buf[i++] = (u8) ((ns_coeff2_2k & 0x003fc000) >> 14);
|
||||
buf[i++] = (u8) ((ns_coeff2_2k & 0x00003fc0) >> 6);
|
||||
buf[i++] = (u8) ((ns_coeff2_2k & 0x0000003f));
|
||||
buf[i++] = (u8) ((ns_coeff1_8191nu & 0x03000000) >> 24);
|
||||
buf[i++] = (u8) ((ns_coeff1_8191nu & 0x00ffc000) >> 16);
|
||||
buf[i++] = (u8) ((ns_coeff1_8191nu & 0x0000ff00) >> 8);
|
||||
buf[i++] = (u8) ((ns_coeff1_8191nu & 0x000000ff));
|
||||
buf[i++] = (u8) ((ns_coeff1_8192nu & 0x03000000) >> 24);
|
||||
buf[i++] = (u8) ((ns_coeff1_8192nu & 0x00ffc000) >> 16);
|
||||
buf[i++] = (u8) ((ns_coeff1_8192nu & 0x0000ff00) >> 8);
|
||||
buf[i++] = (u8) ((ns_coeff1_8192nu & 0x000000ff));
|
||||
buf[i++] = (u8) ((ns_coeff1_8193nu & 0x03000000) >> 24);
|
||||
buf[i++] = (u8) ((ns_coeff1_8193nu & 0x00ffc000) >> 16);
|
||||
buf[i++] = (u8) ((ns_coeff1_8193nu & 0x0000ff00) >> 8);
|
||||
buf[i++] = (u8) ((ns_coeff1_8193nu & 0x000000ff));
|
||||
buf[i++] = (u8) ((ns_coeff2_8k & 0x01c00000) >> 22);
|
||||
buf[i++] = (u8) ((ns_coeff2_8k & 0x003fc000) >> 14);
|
||||
buf[i++] = (u8) ((ns_coeff2_8k & 0x00003fc0) >> 6);
|
||||
buf[i++] = (u8) ((ns_coeff2_8k & 0x0000003f));
|
||||
if (!found) {
|
||||
err("invalid bw or clock");
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
deb_info("%s: coeff:", __func__);
|
||||
debug_dump(buf, sizeof(buf), deb_info);
|
||||
deb_info("%s: coeff: ", __func__);
|
||||
debug_dump(coeff_table[i].val, sizeof(coeff_table[i].val), deb_info);
|
||||
|
||||
/* program */
|
||||
for (i = 0; i < sizeof(buf); i++) {
|
||||
ret = af9013_write_reg(state, 0xae00 + i, buf[i]);
|
||||
for (j = 0; j < sizeof(coeff_table[i].val); j++) {
|
||||
ret = af9013_write_reg(state, 0xae00 + j,
|
||||
coeff_table[i].val[j]);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -486,6 +341,19 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw)
|
|||
if_sample_freq = 4300000; /* 4.3 MHz */
|
||||
break;
|
||||
}
|
||||
} else if (state->config.tuner == AF9013_TUNER_TDA18218) {
|
||||
switch (bw) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
if_sample_freq = 3000000; /* 3 MHz */
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
if_sample_freq = 3500000; /* 3.5 MHz */
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
default:
|
||||
if_sample_freq = 4000000; /* 4 MHz */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (if_sample_freq > (adc_freq / 2))
|
||||
|
|
@ -1097,45 +965,31 @@ static int af9013_update_signal_strength(struct dvb_frontend *fe)
|
|||
{
|
||||
struct af9013_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
u8 tmp0;
|
||||
u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80;
|
||||
u8 rf_gain, if_gain;
|
||||
int signal_strength;
|
||||
|
||||
deb_info("%s\n", __func__);
|
||||
|
||||
state->signal_strength = 0;
|
||||
|
||||
ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0);
|
||||
if (ret)
|
||||
goto error;
|
||||
if (tmp0) {
|
||||
ret = af9013_read_reg(state, 0x9bbd, &rf_50);
|
||||
if (ret)
|
||||
goto error;
|
||||
ret = af9013_read_reg(state, 0x9bd0, &rf_80);
|
||||
if (ret)
|
||||
goto error;
|
||||
ret = af9013_read_reg(state, 0x9be2, &if_50);
|
||||
if (ret)
|
||||
goto error;
|
||||
ret = af9013_read_reg(state, 0x9be4, &if_80);
|
||||
if (ret)
|
||||
goto error;
|
||||
if (state->signal_strength_en) {
|
||||
ret = af9013_read_reg(state, 0xd07c, &rf_gain);
|
||||
if (ret)
|
||||
goto error;
|
||||
ret = af9013_read_reg(state, 0xd07d, &if_gain);
|
||||
if (ret)
|
||||
goto error;
|
||||
signal_strength = (0xffff / (9 * (rf_50 + if_50) - \
|
||||
11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \
|
||||
11 * (rf_80 + if_80));
|
||||
signal_strength = (0xffff / \
|
||||
(9 * (state->rf_50 + state->if_50) - \
|
||||
11 * (state->rf_80 + state->if_80))) * \
|
||||
(10 * (rf_gain + if_gain) - \
|
||||
11 * (state->rf_80 + state->if_80));
|
||||
if (signal_strength < 0)
|
||||
signal_strength = 0;
|
||||
else if (signal_strength > 0xffff)
|
||||
signal_strength = 0xffff;
|
||||
|
||||
state->signal_strength = signal_strength;
|
||||
} else {
|
||||
state->signal_strength = 0;
|
||||
}
|
||||
|
||||
error:
|
||||
|
|
@ -1368,6 +1222,7 @@ static int af9013_init(struct dvb_frontend *fe)
|
|||
break;
|
||||
case AF9013_TUNER_MXL5005D:
|
||||
case AF9013_TUNER_MXL5005R:
|
||||
case AF9013_TUNER_MXL5007T:
|
||||
len = ARRAY_SIZE(tuner_init_mxl5005);
|
||||
init = tuner_init_mxl5005;
|
||||
break;
|
||||
|
|
@ -1393,6 +1248,7 @@ static int af9013_init(struct dvb_frontend *fe)
|
|||
init = tuner_init_mt2060_2;
|
||||
break;
|
||||
case AF9013_TUNER_TDA18271:
|
||||
case AF9013_TUNER_TDA18218:
|
||||
len = ARRAY_SIZE(tuner_init_tda18271);
|
||||
init = tuner_init_tda18271;
|
||||
break;
|
||||
|
|
@ -1438,6 +1294,27 @@ static int af9013_init(struct dvb_frontend *fe)
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
/* read values needed for signal strength calculation */
|
||||
ret = af9013_read_reg_bits(state, 0x9bee, 0, 1,
|
||||
&state->signal_strength_en);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (state->signal_strength_en) {
|
||||
ret = af9013_read_reg(state, 0x9bbd, &state->rf_50);
|
||||
if (ret)
|
||||
goto error;
|
||||
ret = af9013_read_reg(state, 0x9bd0, &state->rf_80);
|
||||
if (ret)
|
||||
goto error;
|
||||
ret = af9013_read_reg(state, 0x9be2, &state->if_50);
|
||||
if (ret)
|
||||
goto error;
|
||||
ret = af9013_read_reg(state, 0x9be4, &state->if_80);
|
||||
if (ret)
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ enum af9013_tuner {
|
|||
AF9013_TUNER_MT2060_2 = 147, /* Microtune */
|
||||
AF9013_TUNER_TDA18271 = 156, /* NXP */
|
||||
AF9013_TUNER_QT1010A = 162, /* Quantek */
|
||||
AF9013_TUNER_MXL5007T = 177, /* MaxLinear */
|
||||
AF9013_TUNER_TDA18218 = 179, /* NXP */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,56 @@ struct snr_table {
|
|||
u8 snr;
|
||||
};
|
||||
|
||||
struct coeff {
|
||||
u32 adc_clock;
|
||||
fe_bandwidth_t bw;
|
||||
u8 val[24];
|
||||
};
|
||||
|
||||
/* pre-calculated coeff lookup table */
|
||||
static struct coeff coeff_table[] = {
|
||||
/* 28.800 MHz */
|
||||
{ 28800, BANDWIDTH_8_MHZ, { 0x02, 0x8a, 0x28, 0xa3, 0x05, 0x14,
|
||||
0x51, 0x11, 0x00, 0xa2, 0x8f, 0x3d, 0x00, 0xa2, 0x8a,
|
||||
0x29, 0x00, 0xa2, 0x85, 0x14, 0x01, 0x45, 0x14, 0x14 } },
|
||||
{ 28800, BANDWIDTH_7_MHZ, { 0x02, 0x38, 0xe3, 0x8e, 0x04, 0x71,
|
||||
0xc7, 0x07, 0x00, 0x8e, 0x3d, 0x55, 0x00, 0x8e, 0x38,
|
||||
0xe4, 0x00, 0x8e, 0x34, 0x72, 0x01, 0x1c, 0x71, 0x32 } },
|
||||
{ 28800, BANDWIDTH_6_MHZ, { 0x01, 0xe7, 0x9e, 0x7a, 0x03, 0xcf,
|
||||
0x3c, 0x3d, 0x00, 0x79, 0xeb, 0x6e, 0x00, 0x79, 0xe7,
|
||||
0x9e, 0x00, 0x79, 0xe3, 0xcf, 0x00, 0xf3, 0xcf, 0x0f } },
|
||||
/* 20.480 MHz */
|
||||
{ 20480, BANDWIDTH_8_MHZ, { 0x03, 0x92, 0x49, 0x26, 0x07, 0x24,
|
||||
0x92, 0x13, 0x00, 0xe4, 0x99, 0x6e, 0x00, 0xe4, 0x92,
|
||||
0x49, 0x00, 0xe4, 0x8b, 0x25, 0x01, 0xc9, 0x24, 0x25 } },
|
||||
{ 20480, BANDWIDTH_7_MHZ, { 0x03, 0x20, 0x00, 0x01, 0x06, 0x40,
|
||||
0x00, 0x00, 0x00, 0xc8, 0x06, 0x40, 0x00, 0xc8, 0x00,
|
||||
0x00, 0x00, 0xc7, 0xf9, 0xc0, 0x01, 0x90, 0x00, 0x00 } },
|
||||
{ 20480, BANDWIDTH_6_MHZ, { 0x02, 0xad, 0xb6, 0xdc, 0x05, 0x5b,
|
||||
0x6d, 0x2e, 0x00, 0xab, 0x73, 0x13, 0x00, 0xab, 0x6d,
|
||||
0xb7, 0x00, 0xab, 0x68, 0x5c, 0x01, 0x56, 0xdb, 0x1c } },
|
||||
/* 28.000 MHz */
|
||||
{ 28000, BANDWIDTH_8_MHZ, { 0x02, 0x9c, 0xbc, 0x15, 0x05, 0x39,
|
||||
0x78, 0x0a, 0x00, 0xa7, 0x34, 0x3f, 0x00, 0xa7, 0x2f,
|
||||
0x05, 0x00, 0xa7, 0x29, 0xcc, 0x01, 0x4e, 0x5e, 0x03 } },
|
||||
{ 28000, BANDWIDTH_7_MHZ, { 0x02, 0x49, 0x24, 0x92, 0x04, 0x92,
|
||||
0x49, 0x09, 0x00, 0x92, 0x4d, 0xb7, 0x00, 0x92, 0x49,
|
||||
0x25, 0x00, 0x92, 0x44, 0x92, 0x01, 0x24, 0x92, 0x12 } },
|
||||
{ 28000, BANDWIDTH_6_MHZ, { 0x01, 0xf5, 0x8d, 0x10, 0x03, 0xeb,
|
||||
0x1a, 0x08, 0x00, 0x7d, 0x67, 0x2f, 0x00, 0x7d, 0x63,
|
||||
0x44, 0x00, 0x7d, 0x5f, 0x59, 0x00, 0xfa, 0xc6, 0x22 } },
|
||||
/* 25.000 MHz */
|
||||
{ 25000, BANDWIDTH_8_MHZ, { 0x02, 0xec, 0xfb, 0x9d, 0x05, 0xd9,
|
||||
0xf7, 0x0e, 0x00, 0xbb, 0x44, 0xc1, 0x00, 0xbb, 0x3e,
|
||||
0xe7, 0x00, 0xbb, 0x39, 0x0d, 0x01, 0x76, 0x7d, 0x34 } },
|
||||
{ 25000, BANDWIDTH_7_MHZ, { 0x02, 0x8f, 0x5c, 0x29, 0x05, 0x1e,
|
||||
0xb8, 0x14, 0x00, 0xa3, 0xdc, 0x29, 0x00, 0xa3, 0xd7,
|
||||
0x0a, 0x00, 0xa3, 0xd1, 0xec, 0x01, 0x47, 0xae, 0x05 } },
|
||||
{ 25000, BANDWIDTH_6_MHZ, { 0x02, 0x31, 0xbc, 0xb5, 0x04, 0x63,
|
||||
0x79, 0x1b, 0x00, 0x8c, 0x73, 0x91, 0x00, 0x8c, 0x6f,
|
||||
0x2d, 0x00, 0x8c, 0x6a, 0xca, 0x01, 0x18, 0xde, 0x17 } },
|
||||
};
|
||||
|
||||
/* QPSK SNR lookup table */
|
||||
static struct snr_table qpsk_snr_table[] = {
|
||||
{ 0x0b4771, 0 },
|
||||
|
|
@ -480,9 +530,10 @@ static struct regdesc tuner_init_mxl5003d[] = {
|
|||
{ 0x9bd9, 0, 8, 0x08 },
|
||||
};
|
||||
|
||||
/* MaxLinear MXL5005 tuner init
|
||||
/* MaxLinear MXL5005S & MXL5007T tuner init
|
||||
AF9013_TUNER_MXL5005D = 13
|
||||
AF9013_TUNER_MXL5005R = 30 */
|
||||
AF9013_TUNER_MXL5005R = 30
|
||||
AF9013_TUNER_MXL5007T = 177 */
|
||||
static struct regdesc tuner_init_mxl5005[] = {
|
||||
{ 0x9bd5, 0, 8, 0x01 },
|
||||
{ 0x9bd6, 0, 8, 0x07 },
|
||||
|
|
@ -791,8 +842,9 @@ static struct regdesc tuner_init_unknown[] = {
|
|||
{ 0x9bd9, 0, 8, 0x08 },
|
||||
};
|
||||
|
||||
/* NXP TDA18271 tuner init
|
||||
AF9013_TUNER_TDA18271 = 156 */
|
||||
/* NXP TDA18271 & TDA18218 tuner init
|
||||
AF9013_TUNER_TDA18271 = 156
|
||||
AF9013_TUNER_TDA18218 = 179 */
|
||||
static struct regdesc tuner_init_tda18271[] = {
|
||||
{ 0x9bd5, 0, 8, 0x01 },
|
||||
{ 0x9bd6, 0, 8, 0x04 },
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
#include <linux/delay.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-chip-ident.h>
|
||||
#include <media/v4l2-i2c-drv.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include "au8522.h"
|
||||
#include "au8522_priv.h"
|
||||
|
|
@ -831,9 +830,25 @@ static const struct i2c_device_id au8522_id[] = {
|
|||
|
||||
MODULE_DEVICE_TABLE(i2c, au8522_id);
|
||||
|
||||
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
|
||||
.name = "au8522",
|
||||
.probe = au8522_probe,
|
||||
.remove = au8522_remove,
|
||||
.id_table = au8522_id,
|
||||
static struct i2c_driver au8522_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "au8522",
|
||||
},
|
||||
.probe = au8522_probe,
|
||||
.remove = au8522_remove,
|
||||
.id_table = au8522_id,
|
||||
};
|
||||
|
||||
static __init int init_au8522(void)
|
||||
{
|
||||
return i2c_add_driver(&au8522_driver);
|
||||
}
|
||||
|
||||
static __exit void exit_au8522(void)
|
||||
{
|
||||
i2c_del_driver(&au8522_driver);
|
||||
}
|
||||
|
||||
module_init(init_au8522);
|
||||
module_exit(exit_au8522);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ MODULE_PARM_DESC(debug, "Enable verbose debug messages");
|
|||
#define dprintk if (debug) printk
|
||||
|
||||
/* Register values to initialise the demod */
|
||||
static u8 init_tab[] = {
|
||||
static const u8 init_tab[] = {
|
||||
0x00, 0x00, /* Stop aquisition */
|
||||
0x0B, 0x06,
|
||||
0x09, 0x01,
|
||||
|
|
@ -92,52 +92,56 @@ static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data)
|
|||
|
||||
ret = i2c_transfer(state->i2c, &msg, 1);
|
||||
|
||||
if (ret != 1)
|
||||
if (unlikely(ret != 1)) {
|
||||
printk(KERN_ERR
|
||||
"%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
|
||||
__func__, reg, data, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (ret != 1) ? -1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 cx22702_readreg(struct cx22702_state *state, u8 reg)
|
||||
{
|
||||
int ret;
|
||||
u8 b0[] = { reg };
|
||||
u8 b1[] = { 0 };
|
||||
u8 data;
|
||||
|
||||
struct i2c_msg msg[] = {
|
||||
{ .addr = state->config->demod_address, .flags = 0,
|
||||
.buf = b0, .len = 1 },
|
||||
.buf = ®, .len = 1 },
|
||||
{ .addr = state->config->demod_address, .flags = I2C_M_RD,
|
||||
.buf = b1, .len = 1 } };
|
||||
.buf = &data, .len = 1 } };
|
||||
|
||||
ret = i2c_transfer(state->i2c, msg, 2);
|
||||
|
||||
if (ret != 2)
|
||||
printk(KERN_ERR "%s: readreg error (ret == %i)\n",
|
||||
__func__, ret);
|
||||
if (unlikely(ret != 2)) {
|
||||
printk(KERN_ERR "%s: error (reg == 0x%02x, ret == %i)\n",
|
||||
__func__, reg, ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return b1[0];
|
||||
return data;
|
||||
}
|
||||
|
||||
static int cx22702_set_inversion(struct cx22702_state *state, int inversion)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
val = cx22702_readreg(state, 0x0C);
|
||||
switch (inversion) {
|
||||
case INVERSION_AUTO:
|
||||
return -EOPNOTSUPP;
|
||||
case INVERSION_ON:
|
||||
val = cx22702_readreg(state, 0x0C);
|
||||
return cx22702_writereg(state, 0x0C, val | 0x01);
|
||||
val |= 0x01;
|
||||
break;
|
||||
case INVERSION_OFF:
|
||||
val = cx22702_readreg(state, 0x0C);
|
||||
return cx22702_writereg(state, 0x0C, val & 0xfe);
|
||||
val &= 0xfe;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return cx22702_writereg(state, 0x0C, val);
|
||||
}
|
||||
|
||||
/* Retrieve the demod settings */
|
||||
|
|
@ -244,13 +248,15 @@ static int cx22702_get_tps(struct cx22702_state *state,
|
|||
static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||
{
|
||||
struct cx22702_state *state = fe->demodulator_priv;
|
||||
u8 val;
|
||||
|
||||
dprintk("%s(%d)\n", __func__, enable);
|
||||
val = cx22702_readreg(state, 0x0D);
|
||||
if (enable)
|
||||
return cx22702_writereg(state, 0x0D,
|
||||
cx22702_readreg(state, 0x0D) & 0xfe);
|
||||
val &= 0xfe;
|
||||
else
|
||||
return cx22702_writereg(state, 0x0D,
|
||||
cx22702_readreg(state, 0x0D) | 1);
|
||||
val |= 0x01;
|
||||
return cx22702_writereg(state, 0x0D, val);
|
||||
}
|
||||
|
||||
/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
|
||||
|
|
@ -270,23 +276,21 @@ static int cx22702_set_tps(struct dvb_frontend *fe,
|
|||
cx22702_set_inversion(state, p->inversion);
|
||||
|
||||
/* set bandwidth */
|
||||
val = cx22702_readreg(state, 0x0C) & 0xcf;
|
||||
switch (p->u.ofdm.bandwidth) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
cx22702_writereg(state, 0x0C,
|
||||
(cx22702_readreg(state, 0x0C) & 0xcf) | 0x20);
|
||||
val |= 0x20;
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
cx22702_writereg(state, 0x0C,
|
||||
(cx22702_readreg(state, 0x0C) & 0xcf) | 0x10);
|
||||
val |= 0x10;
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
cx22702_writereg(state, 0x0C,
|
||||
cx22702_readreg(state, 0x0C) & 0xcf);
|
||||
break;
|
||||
default:
|
||||
dprintk("%s: invalid bandwidth\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
cx22702_writereg(state, 0x0C, val);
|
||||
|
||||
p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */
|
||||
|
||||
|
|
@ -312,33 +316,31 @@ static int cx22702_set_tps(struct dvb_frontend *fe,
|
|||
}
|
||||
|
||||
/* manually programmed values */
|
||||
val = 0;
|
||||
switch (p->u.ofdm.constellation) {
|
||||
switch (p->u.ofdm.constellation) { /* mask 0x18 */
|
||||
case QPSK:
|
||||
val = (val & 0xe7);
|
||||
val = 0x00;
|
||||
break;
|
||||
case QAM_16:
|
||||
val = (val & 0xe7) | 0x08;
|
||||
val = 0x08;
|
||||
break;
|
||||
case QAM_64:
|
||||
val = (val & 0xe7) | 0x10;
|
||||
val = 0x10;
|
||||
break;
|
||||
default:
|
||||
dprintk("%s: invalid constellation\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (p->u.ofdm.hierarchy_information) {
|
||||
switch (p->u.ofdm.hierarchy_information) { /* mask 0x07 */
|
||||
case HIERARCHY_NONE:
|
||||
val = (val & 0xf8);
|
||||
break;
|
||||
case HIERARCHY_1:
|
||||
val = (val & 0xf8) | 1;
|
||||
val |= 0x01;
|
||||
break;
|
||||
case HIERARCHY_2:
|
||||
val = (val & 0xf8) | 2;
|
||||
val |= 0x02;
|
||||
break;
|
||||
case HIERARCHY_4:
|
||||
val = (val & 0xf8) | 3;
|
||||
val |= 0x03;
|
||||
break;
|
||||
default:
|
||||
dprintk("%s: invalid hierarchy\n", __func__);
|
||||
|
|
@ -346,44 +348,42 @@ static int cx22702_set_tps(struct dvb_frontend *fe,
|
|||
}
|
||||
cx22702_writereg(state, 0x06, val);
|
||||
|
||||
val = 0;
|
||||
switch (p->u.ofdm.code_rate_HP) {
|
||||
switch (p->u.ofdm.code_rate_HP) { /* mask 0x38 */
|
||||
case FEC_NONE:
|
||||
case FEC_1_2:
|
||||
val = (val & 0xc7);
|
||||
val = 0x00;
|
||||
break;
|
||||
case FEC_2_3:
|
||||
val = (val & 0xc7) | 0x08;
|
||||
val = 0x08;
|
||||
break;
|
||||
case FEC_3_4:
|
||||
val = (val & 0xc7) | 0x10;
|
||||
val = 0x10;
|
||||
break;
|
||||
case FEC_5_6:
|
||||
val = (val & 0xc7) | 0x18;
|
||||
val = 0x18;
|
||||
break;
|
||||
case FEC_7_8:
|
||||
val = (val & 0xc7) | 0x20;
|
||||
val = 0x20;
|
||||
break;
|
||||
default:
|
||||
dprintk("%s: invalid code_rate_HP\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (p->u.ofdm.code_rate_LP) {
|
||||
switch (p->u.ofdm.code_rate_LP) { /* mask 0x07 */
|
||||
case FEC_NONE:
|
||||
case FEC_1_2:
|
||||
val = (val & 0xf8);
|
||||
break;
|
||||
case FEC_2_3:
|
||||
val = (val & 0xf8) | 1;
|
||||
val |= 0x01;
|
||||
break;
|
||||
case FEC_3_4:
|
||||
val = (val & 0xf8) | 2;
|
||||
val |= 0x02;
|
||||
break;
|
||||
case FEC_5_6:
|
||||
val = (val & 0xf8) | 3;
|
||||
val |= 0x03;
|
||||
break;
|
||||
case FEC_7_8:
|
||||
val = (val & 0xf8) | 4;
|
||||
val |= 0x04;
|
||||
break;
|
||||
default:
|
||||
dprintk("%s: invalid code_rate_LP\n", __func__);
|
||||
|
|
@ -391,30 +391,28 @@ static int cx22702_set_tps(struct dvb_frontend *fe,
|
|||
}
|
||||
cx22702_writereg(state, 0x07, val);
|
||||
|
||||
val = 0;
|
||||
switch (p->u.ofdm.guard_interval) {
|
||||
switch (p->u.ofdm.guard_interval) { /* mask 0x0c */
|
||||
case GUARD_INTERVAL_1_32:
|
||||
val = (val & 0xf3);
|
||||
val = 0x00;
|
||||
break;
|
||||
case GUARD_INTERVAL_1_16:
|
||||
val = (val & 0xf3) | 0x04;
|
||||
val = 0x04;
|
||||
break;
|
||||
case GUARD_INTERVAL_1_8:
|
||||
val = (val & 0xf3) | 0x08;
|
||||
val = 0x08;
|
||||
break;
|
||||
case GUARD_INTERVAL_1_4:
|
||||
val = (val & 0xf3) | 0x0c;
|
||||
val = 0x0c;
|
||||
break;
|
||||
default:
|
||||
dprintk("%s: invalid guard_interval\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (p->u.ofdm.transmission_mode) {
|
||||
switch (p->u.ofdm.transmission_mode) { /* mask 0x03 */
|
||||
case TRANSMISSION_MODE_2K:
|
||||
val = (val & 0xfc);
|
||||
break;
|
||||
case TRANSMISSION_MODE_8K:
|
||||
val = (val & 0xfc) | 1;
|
||||
val |= 0x1;
|
||||
break;
|
||||
default:
|
||||
dprintk("%s: invalid transmission_mode\n", __func__);
|
||||
|
|
@ -505,7 +503,7 @@ static int cx22702_read_signal_strength(struct dvb_frontend *fe,
|
|||
{
|
||||
struct cx22702_state *state = fe->demodulator_priv;
|
||||
|
||||
u16 rs_ber = 0;
|
||||
u16 rs_ber;
|
||||
rs_ber = cx22702_readreg(state, 0x23);
|
||||
*signal_strength = (rs_ber << 8) | rs_ber;
|
||||
|
||||
|
|
@ -516,7 +514,7 @@ static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr)
|
|||
{
|
||||
struct cx22702_state *state = fe->demodulator_priv;
|
||||
|
||||
u16 rs_ber = 0;
|
||||
u16 rs_ber;
|
||||
if (cx22702_readreg(state, 0xE4) & 0x02) {
|
||||
/* Realtime statistics */
|
||||
rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
|
||||
|
|
@ -572,7 +570,7 @@ static void cx22702_release(struct dvb_frontend *fe)
|
|||
kfree(state);
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops cx22702_ops;
|
||||
static const struct dvb_frontend_ops cx22702_ops;
|
||||
|
||||
struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
|
|
@ -587,7 +585,6 @@ struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
|
|||
/* setup the state */
|
||||
state->config = config;
|
||||
state->i2c = i2c;
|
||||
state->prevUCBlocks = 0;
|
||||
|
||||
/* check if the demod is there */
|
||||
if (cx22702_readreg(state, 0x1f) != 0x3)
|
||||
|
|
@ -605,7 +602,7 @@ error:
|
|||
}
|
||||
EXPORT_SYMBOL(cx22702_attach);
|
||||
|
||||
static struct dvb_frontend_ops cx22702_ops = {
|
||||
static const struct dvb_frontend_ops cx22702_ops = {
|
||||
|
||||
.info = {
|
||||
.name = "Conexant CX22702 DVB-T",
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
|
|||
|
||||
}
|
||||
|
||||
static int _cx24110_pll_write (struct dvb_frontend* fe, u8 *buf, int len)
|
||||
static int _cx24110_pll_write (struct dvb_frontend* fe, const u8 buf[], int len)
|
||||
{
|
||||
struct cx24110_state *state = fe->demodulator_priv;
|
||||
|
||||
|
|
|
|||
|
|
@ -1108,7 +1108,6 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
|
|||
|
||||
strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
|
||||
sizeof(state->tuner_i2c_adapter.name));
|
||||
state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL,
|
||||
state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo;
|
||||
state->tuner_i2c_adapter.algo_data = NULL;
|
||||
i2c_set_adapdata(&state->tuner_i2c_adapter, state);
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
|
|||
struct dibx000_i2c_master *mst)
|
||||
{
|
||||
strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
|
||||
i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->algo = algo;
|
||||
i2c_adap->algo_data = NULL;
|
||||
i2c_set_adapdata(i2c_adap, mst);
|
||||
if (i2c_add_adapter(i2c_adap) < 0)
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ static int write_fw(struct drx397xD_state *s, enum blob_ix ix)
|
|||
exit_rc:
|
||||
read_unlock(&fw[s->chip_rev].lock);
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Function is not endian safe, use the RD16 wrapper below */
|
||||
|
|
|
|||
323
drivers/media/dvb/frontends/ix2505v.c
Normal file
323
drivers/media/dvb/frontends/ix2505v.c
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
/**
|
||||
* Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
|
||||
*
|
||||
* Copyright (C) 2010 Malcolm Priestley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License Version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "ix2505v.h"
|
||||
|
||||
static int ix2505v_debug;
|
||||
#define dprintk(level, args...) do { \
|
||||
if (ix2505v_debug & level) \
|
||||
printk(KERN_DEBUG "ix2505v: " args); \
|
||||
} while (0)
|
||||
|
||||
#define deb_info(args...) dprintk(0x01, args)
|
||||
#define deb_i2c(args...) dprintk(0x02, args)
|
||||
|
||||
struct ix2505v_state {
|
||||
struct i2c_adapter *i2c;
|
||||
const struct ix2505v_config *config;
|
||||
u32 frequency;
|
||||
};
|
||||
|
||||
/**
|
||||
* Data read format of the Sharp IX2505V B0017
|
||||
*
|
||||
* byte1: 1 | 1 | 0 | 0 | 0 | MA1 | MA0 | 1
|
||||
* byte2: POR | FL | RD2 | RD1 | RD0 | X | X | X
|
||||
*
|
||||
* byte1 = address
|
||||
* byte2;
|
||||
* POR = Power on Reset (VCC H=<2.2v L=>2.2v)
|
||||
* FL = Phase Lock (H=lock L=unlock)
|
||||
* RD0-2 = Reserved internal operations
|
||||
*
|
||||
* Only POR can be used to check the tuner is present
|
||||
*
|
||||
* Caution: after byte2 the I2C reverts to write mode continuing to read
|
||||
* may corrupt tuning data.
|
||||
*
|
||||
*/
|
||||
|
||||
static int ix2505v_read_status_reg(struct ix2505v_state *state)
|
||||
{
|
||||
u8 addr = state->config->tuner_address;
|
||||
u8 b2[] = {0};
|
||||
int ret;
|
||||
|
||||
struct i2c_msg msg[1] = {
|
||||
{ .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 }
|
||||
};
|
||||
|
||||
ret = i2c_transfer(state->i2c, msg, 1);
|
||||
deb_i2c("Read %s ", __func__);
|
||||
|
||||
return (ret = 1) ? (int) b2[0] : -1;
|
||||
}
|
||||
|
||||
static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)
|
||||
{
|
||||
struct i2c_msg msg[1] = {
|
||||
{ .addr = state->config->tuner_address, .flags = 0,
|
||||
.buf = buf, .len = count },
|
||||
};
|
||||
|
||||
int ret;
|
||||
|
||||
ret = i2c_transfer(state->i2c, msg, 1);
|
||||
|
||||
if (ret != 1) {
|
||||
deb_i2c("%s: i2c error, ret=%d\n", __func__, ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ix2505v_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct ix2505v_state *state = fe->tuner_priv;
|
||||
|
||||
fe->tuner_priv = NULL;
|
||||
kfree(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data write format of the Sharp IX2505V B0017
|
||||
*
|
||||
* byte1: 1 | 1 | 0 | 0 | 0 | 0(MA1)| 0(MA0)| 0
|
||||
* byte2: 0 | BG1 | BG2 | N8 | N7 | N6 | N5 | N4
|
||||
* byte3: N3 | N2 | N1 | A5 | A4 | A3 | A2 | A1
|
||||
* byte4: 1 | 1(C1) | 1(C0) | PD5 | PD4 | TM | 0(RTS)| 1(REF)
|
||||
* byte5: BA2 | BA1 | BA0 | PSC | PD3 |PD2/TS2|DIV/TS1|PD0/TS0
|
||||
*
|
||||
* byte1 = address
|
||||
*
|
||||
* Write order
|
||||
* 1) byte1 -> byte2 -> byte3 -> byte4 -> byte5
|
||||
* 2) byte1 -> byte4 -> byte5 -> byte2 -> byte3
|
||||
* 3) byte1 -> byte2 -> byte3 -> byte4
|
||||
* 4) byte1 -> byte4 -> byte5 -> byte2
|
||||
* 5) byte1 -> byte2 -> byte3
|
||||
* 6) byte1 -> byte4 -> byte5
|
||||
* 7) byte1 -> byte2
|
||||
* 8) byte1 -> byte4
|
||||
*
|
||||
* Recommended Setup
|
||||
* 1 -> 8 -> 6
|
||||
*/
|
||||
|
||||
static int ix2505v_set_params(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *params)
|
||||
{
|
||||
struct ix2505v_state *state = fe->tuner_priv;
|
||||
u32 frequency = params->frequency;
|
||||
u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000;
|
||||
u32 div_factor, N , A, x;
|
||||
int ret = 0, len;
|
||||
u8 gain, cc, ref, psc, local_osc, lpf;
|
||||
u8 data[4] = {0};
|
||||
|
||||
if ((frequency < fe->ops.info.frequency_min)
|
||||
|| (frequency > fe->ops.info.frequency_max))
|
||||
return -EINVAL;
|
||||
|
||||
if (state->config->tuner_gain)
|
||||
gain = (state->config->tuner_gain < 4)
|
||||
? state->config->tuner_gain : 0;
|
||||
else
|
||||
gain = 0x0;
|
||||
|
||||
if (state->config->tuner_chargepump)
|
||||
cc = state->config->tuner_chargepump;
|
||||
else
|
||||
cc = 0x3;
|
||||
|
||||
ref = 8; /* REF =1 */
|
||||
psc = 32; /* PSC = 0 */
|
||||
|
||||
div_factor = (frequency * ref) / 40; /* local osc = 4Mhz */
|
||||
x = div_factor / psc;
|
||||
N = x/100;
|
||||
A = ((x - (N * 100)) * psc) / 100;
|
||||
|
||||
data[0] = ((gain & 0x3) << 5) | (N >> 3);
|
||||
data[1] = (N << 5) | (A & 0x1f);
|
||||
data[2] = 0x81 | ((cc & 0x3) << 5) ; /*PD5,PD4 & TM = 0|C1,C0|REF=1*/
|
||||
|
||||
deb_info("Frq=%d x=%d N=%d A=%d\n", frequency, x, N, A);
|
||||
|
||||
if (frequency <= 1065000)
|
||||
local_osc = (6 << 5) | 2;
|
||||
else if (frequency <= 1170000)
|
||||
local_osc = (7 << 5) | 2;
|
||||
else if (frequency <= 1300000)
|
||||
local_osc = (1 << 5);
|
||||
else if (frequency <= 1445000)
|
||||
local_osc = (2 << 5);
|
||||
else if (frequency <= 1607000)
|
||||
local_osc = (3 << 5);
|
||||
else if (frequency <= 1778000)
|
||||
local_osc = (4 << 5);
|
||||
else if (frequency <= 1942000)
|
||||
local_osc = (5 << 5);
|
||||
else /*frequency up to 2150000*/
|
||||
local_osc = (6 << 5);
|
||||
|
||||
data[3] = local_osc; /* all other bits set 0 */
|
||||
|
||||
if (b_w <= 10000)
|
||||
lpf = 0xc;
|
||||
else if (b_w <= 12000)
|
||||
lpf = 0x2;
|
||||
else if (b_w <= 14000)
|
||||
lpf = 0xa;
|
||||
else if (b_w <= 16000)
|
||||
lpf = 0x6;
|
||||
else if (b_w <= 18000)
|
||||
lpf = 0xe;
|
||||
else if (b_w <= 20000)
|
||||
lpf = 0x1;
|
||||
else if (b_w <= 22000)
|
||||
lpf = 0x9;
|
||||
else if (b_w <= 24000)
|
||||
lpf = 0x5;
|
||||
else if (b_w <= 26000)
|
||||
lpf = 0xd;
|
||||
else if (b_w <= 28000)
|
||||
lpf = 0x3;
|
||||
else
|
||||
lpf = 0xb;
|
||||
|
||||
deb_info("Osc=%x b_w=%x lpf=%x\n", local_osc, b_w, lpf);
|
||||
deb_info("Data 0=[%x%x%x%x]\n", data[0], data[1], data[2], data[3]);
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
len = sizeof(data);
|
||||
|
||||
ret |= ix2505v_write(state, data, len);
|
||||
|
||||
data[2] |= 0x4; /* set TM = 1 other bits same */
|
||||
|
||||
len = 1;
|
||||
ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */
|
||||
|
||||
msleep(10);
|
||||
|
||||
data[2] |= ((lpf >> 2) & 0x3) << 3; /* lpf */
|
||||
data[3] |= (lpf & 0x3) << 2;
|
||||
|
||||
deb_info("Data 2=[%x%x]\n", data[2], data[3]);
|
||||
|
||||
len = 2;
|
||||
ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
if (state->config->min_delay_ms)
|
||||
msleep(state->config->min_delay_ms);
|
||||
|
||||
state->frequency = frequency;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
struct ix2505v_state *state = fe->tuner_priv;
|
||||
|
||||
*frequency = state->frequency;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_tuner_ops ix2505v_tuner_ops = {
|
||||
.info = {
|
||||
.name = "Sharp IX2505V (B0017)",
|
||||
.frequency_min = 950000,
|
||||
.frequency_max = 2175000
|
||||
},
|
||||
.release = ix2505v_release,
|
||||
.set_params = ix2505v_set_params,
|
||||
.get_frequency = ix2505v_get_frequency,
|
||||
};
|
||||
|
||||
struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
|
||||
const struct ix2505v_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct ix2505v_state *state = NULL;
|
||||
int ret;
|
||||
|
||||
if (NULL == config) {
|
||||
deb_i2c("%s: no config ", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
state = kzalloc(sizeof(struct ix2505v_state), GFP_KERNEL);
|
||||
if (NULL == state)
|
||||
return NULL;
|
||||
|
||||
state->config = config;
|
||||
state->i2c = i2c;
|
||||
|
||||
if (state->config->tuner_write_only) {
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
ret = ix2505v_read_status_reg(state);
|
||||
|
||||
if (ret & 0x80) {
|
||||
deb_i2c("%s: No IX2505V found\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
}
|
||||
|
||||
fe->tuner_priv = state;
|
||||
|
||||
memcpy(&fe->ops.tuner_ops, &ix2505v_tuner_ops,
|
||||
sizeof(struct dvb_tuner_ops));
|
||||
deb_i2c("%s: initialization (%s addr=0x%02x) ok\n",
|
||||
__func__, fe->ops.tuner_ops.info.name, config->tuner_address);
|
||||
|
||||
return fe;
|
||||
|
||||
error:
|
||||
ix2505v_release(fe);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(ix2505v_attach);
|
||||
|
||||
module_param_named(debug, ix2505v_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
|
||||
MODULE_DESCRIPTION("DVB IX2505V tuner driver");
|
||||
MODULE_AUTHOR("Malcolm Priestley");
|
||||
MODULE_LICENSE("GPL");
|
||||
64
drivers/media/dvb/frontends/ix2505v.h
Normal file
64
drivers/media/dvb/frontends/ix2505v.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
|
||||
*
|
||||
* Copyright (C) 2010 Malcolm Priestley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License Version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef DVB_IX2505V_H
|
||||
#define DVB_IX2505V_H
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
/**
|
||||
* Attach a ix2505v tuner to the supplied frontend structure.
|
||||
*
|
||||
* @param fe Frontend to attach to.
|
||||
* @param config ix2505v_config structure
|
||||
* @return FE pointer on success, NULL on failure.
|
||||
*/
|
||||
|
||||
struct ix2505v_config {
|
||||
u8 tuner_address;
|
||||
|
||||
/*Baseband AMP gain control 0/1=0dB(default) 2=-2bB 3=-4dB */
|
||||
u8 tuner_gain;
|
||||
|
||||
/*Charge pump output +/- 0=120 1=260 2=555 3=1200(default) */
|
||||
u8 tuner_chargepump;
|
||||
|
||||
/* delay after tune */
|
||||
int min_delay_ms;
|
||||
|
||||
/* disables reads*/
|
||||
u8 tuner_write_only;
|
||||
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_IX2505V) || \
|
||||
(defined(CONFIG_DVB_IX2505V_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
|
||||
const struct ix2505v_config *config, struct i2c_adapter *i2c);
|
||||
#else
|
||||
static inline struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
|
||||
const struct ix2505v_config *config, struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DVB_IX2505V_H */
|
||||
|
|
@ -1,380 +0,0 @@
|
|||
/*
|
||||
* Driver for LG ATSC lgdt3304 driver
|
||||
*
|
||||
* Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include "dvb_frontend.h"
|
||||
#include "lgdt3304.h"
|
||||
|
||||
static unsigned int debug = 0;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)");
|
||||
|
||||
#define dprintk(fmt, args...) if (debug) do {\
|
||||
printk("lgdt3304 debug: " fmt, ##args); } while (0)
|
||||
|
||||
struct lgdt3304_state
|
||||
{
|
||||
struct dvb_frontend frontend;
|
||||
fe_modulation_t current_modulation;
|
||||
__u32 snr;
|
||||
__u32 current_frequency;
|
||||
__u8 addr;
|
||||
struct i2c_adapter *i2c;
|
||||
};
|
||||
|
||||
static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len)
|
||||
{
|
||||
struct lgdt3304_state *state = fe->demodulator_priv;
|
||||
struct i2c_msg i2cmsgs = {
|
||||
.addr = state->addr,
|
||||
.flags = 0,
|
||||
.len = 3,
|
||||
.buf = buf
|
||||
};
|
||||
int i;
|
||||
int err;
|
||||
|
||||
for (i=0; i<len-1; i+=3){
|
||||
if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
|
||||
printk("%s i2c_transfer error %d\n", __func__, err);
|
||||
if (err < 0)
|
||||
return err;
|
||||
else
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
i2cmsgs.buf += 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg)
|
||||
{
|
||||
struct lgdt3304_state *state = fe->demodulator_priv;
|
||||
struct i2c_msg i2cmsgs[2];
|
||||
int ret;
|
||||
__u8 buf;
|
||||
|
||||
__u8 regbuf[2] = { reg>>8, reg&0xff };
|
||||
|
||||
i2cmsgs[0].addr = state->addr;
|
||||
i2cmsgs[0].flags = 0;
|
||||
i2cmsgs[0].len = 2;
|
||||
i2cmsgs[0].buf = regbuf;
|
||||
|
||||
i2cmsgs[1].addr = state->addr;
|
||||
i2cmsgs[1].flags = I2C_M_RD;
|
||||
i2cmsgs[1].len = 1;
|
||||
i2cmsgs[1].buf = &buf;
|
||||
|
||||
if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) {
|
||||
printk("%s i2c_transfer error %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val)
|
||||
{
|
||||
struct lgdt3304_state *state = fe->demodulator_priv;
|
||||
char buffer[3] = { reg>>8, reg&0xff, val };
|
||||
int ret;
|
||||
|
||||
struct i2c_msg i2cmsgs = {
|
||||
.addr = state->addr,
|
||||
.flags = 0,
|
||||
.len = 3,
|
||||
.buf=buffer
|
||||
};
|
||||
ret = i2c_transfer(state->i2c, &i2cmsgs, 1);
|
||||
if (ret != 1) {
|
||||
printk("%s i2c_transfer error %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int lgdt3304_soft_Reset(struct dvb_frontend *fe)
|
||||
{
|
||||
lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a);
|
||||
lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b);
|
||||
mdelay(200);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
|
||||
int err = 0;
|
||||
|
||||
static __u8 lgdt3304_vsb8_data[] = {
|
||||
/* 16bit , 8bit */
|
||||
/* regs , val */
|
||||
0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x13,
|
||||
0x00, 0x0d, 0x02,
|
||||
0x00, 0x0e, 0x02,
|
||||
0x00, 0x12, 0x32,
|
||||
0x00, 0x13, 0xc4,
|
||||
0x01, 0x12, 0x17,
|
||||
0x01, 0x13, 0x15,
|
||||
0x01, 0x14, 0x18,
|
||||
0x01, 0x15, 0xff,
|
||||
0x01, 0x16, 0x2c,
|
||||
0x02, 0x14, 0x67,
|
||||
0x02, 0x24, 0x8d,
|
||||
0x04, 0x27, 0x12,
|
||||
0x04, 0x28, 0x4f,
|
||||
0x03, 0x08, 0x80,
|
||||
0x03, 0x09, 0x00,
|
||||
0x03, 0x0d, 0x00,
|
||||
0x03, 0x0e, 0x1c,
|
||||
0x03, 0x14, 0xe1,
|
||||
0x05, 0x0e, 0x5b,
|
||||
};
|
||||
|
||||
/* not yet tested .. */
|
||||
static __u8 lgdt3304_qam64_data[] = {
|
||||
/* 16bit , 8bit */
|
||||
/* regs , val */
|
||||
0x00, 0x00, 0x18,
|
||||
0x00, 0x0d, 0x02,
|
||||
//0x00, 0x0e, 0x02,
|
||||
0x00, 0x12, 0x2a,
|
||||
0x00, 0x13, 0x00,
|
||||
0x03, 0x14, 0xe3,
|
||||
0x03, 0x0e, 0x1c,
|
||||
0x03, 0x08, 0x66,
|
||||
0x03, 0x09, 0x66,
|
||||
0x03, 0x0a, 0x08,
|
||||
0x03, 0x0b, 0x9b,
|
||||
0x05, 0x0e, 0x5b,
|
||||
};
|
||||
|
||||
|
||||
/* tested with KWorld a340 */
|
||||
static __u8 lgdt3304_qam256_data[] = {
|
||||
/* 16bit , 8bit */
|
||||
/* regs , val */
|
||||
0x00, 0x00, 0x01, //0x19,
|
||||
0x00, 0x12, 0x2a,
|
||||
0x00, 0x13, 0x80,
|
||||
0x00, 0x0d, 0x02,
|
||||
0x03, 0x14, 0xe3,
|
||||
|
||||
0x03, 0x0e, 0x1c,
|
||||
0x03, 0x08, 0x66,
|
||||
0x03, 0x09, 0x66,
|
||||
0x03, 0x0a, 0x08,
|
||||
0x03, 0x0b, 0x9b,
|
||||
|
||||
0x03, 0x0d, 0x14,
|
||||
//0x05, 0x0e, 0x5b,
|
||||
0x01, 0x06, 0x4a,
|
||||
0x01, 0x07, 0x3d,
|
||||
0x01, 0x08, 0x70,
|
||||
0x01, 0x09, 0xa3,
|
||||
|
||||
0x05, 0x04, 0xfd,
|
||||
|
||||
0x00, 0x0d, 0x82,
|
||||
|
||||
0x05, 0x0e, 0x5b,
|
||||
|
||||
0x05, 0x0e, 0x5b,
|
||||
|
||||
0x00, 0x02, 0x9a,
|
||||
|
||||
0x00, 0x02, 0x9b,
|
||||
|
||||
0x00, 0x00, 0x01,
|
||||
0x00, 0x12, 0x2a,
|
||||
0x00, 0x13, 0x80,
|
||||
0x00, 0x0d, 0x02,
|
||||
0x03, 0x14, 0xe3,
|
||||
|
||||
0x03, 0x0e, 0x1c,
|
||||
0x03, 0x08, 0x66,
|
||||
0x03, 0x09, 0x66,
|
||||
0x03, 0x0a, 0x08,
|
||||
0x03, 0x0b, 0x9b,
|
||||
|
||||
0x03, 0x0d, 0x14,
|
||||
0x01, 0x06, 0x4a,
|
||||
0x01, 0x07, 0x3d,
|
||||
0x01, 0x08, 0x70,
|
||||
0x01, 0x09, 0xa3,
|
||||
|
||||
0x05, 0x04, 0xfd,
|
||||
|
||||
0x00, 0x0d, 0x82,
|
||||
|
||||
0x05, 0x0e, 0x5b,
|
||||
};
|
||||
|
||||
struct lgdt3304_state *state = fe->demodulator_priv;
|
||||
if (state->current_modulation != param->u.vsb.modulation) {
|
||||
switch(param->u.vsb.modulation) {
|
||||
case VSB_8:
|
||||
err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data,
|
||||
sizeof(lgdt3304_vsb8_data));
|
||||
break;
|
||||
case QAM_64:
|
||||
err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data,
|
||||
sizeof(lgdt3304_qam64_data));
|
||||
break;
|
||||
case QAM_256:
|
||||
err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data,
|
||||
sizeof(lgdt3304_qam256_data));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
printk("%s error setting modulation\n", __func__);
|
||||
} else {
|
||||
state->current_modulation = param->u.vsb.modulation;
|
||||
}
|
||||
}
|
||||
state->current_frequency = param->frequency;
|
||||
|
||||
lgdt3304_soft_Reset(fe);
|
||||
|
||||
|
||||
if (fe->ops.tuner_ops.set_params)
|
||||
fe->ops.tuner_ops.set_params(fe, param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgdt3304_init(struct dvb_frontend *fe) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgdt3304_sleep(struct dvb_frontend *fe) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
{
|
||||
struct lgdt3304_state *state = fe->demodulator_priv;
|
||||
int r011d;
|
||||
int qam_lck;
|
||||
|
||||
*status = 0;
|
||||
dprintk("lgdt read status\n");
|
||||
|
||||
r011d = lgdt3304_i2c_read_reg(fe, 0x011d);
|
||||
|
||||
dprintk("%02x\n", r011d);
|
||||
|
||||
switch(state->current_modulation) {
|
||||
case VSB_8:
|
||||
if (r011d & 0x80) {
|
||||
dprintk("VSB Locked\n");
|
||||
*status |= FE_HAS_CARRIER;
|
||||
*status |= FE_HAS_LOCK;
|
||||
*status |= FE_HAS_SYNC;
|
||||
*status |= FE_HAS_SIGNAL;
|
||||
}
|
||||
break;
|
||||
case QAM_64:
|
||||
case QAM_256:
|
||||
qam_lck = r011d & 0x7;
|
||||
switch(qam_lck) {
|
||||
case 0x0: dprintk("Unlock\n");
|
||||
break;
|
||||
case 0x4: dprintk("1st Lock in acquisition state\n");
|
||||
break;
|
||||
case 0x6: dprintk("2nd Lock in acquisition state\n");
|
||||
break;
|
||||
case 0x7: dprintk("Final Lock in good reception state\n");
|
||||
*status |= FE_HAS_CARRIER;
|
||||
*status |= FE_HAS_LOCK;
|
||||
*status |= FE_HAS_SYNC;
|
||||
*status |= FE_HAS_SIGNAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printk("%s unhandled modulation\n", __func__);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber)
|
||||
{
|
||||
dprintk("read ber\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr)
|
||||
{
|
||||
dprintk("read snr\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
|
||||
{
|
||||
dprintk("read ucblocks\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lgdt3304_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv;
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops demod_lgdt3304={
|
||||
.info = {
|
||||
.name = "LG 3304",
|
||||
.type = FE_ATSC,
|
||||
.frequency_min = 54000000,
|
||||
.frequency_max = 858000000,
|
||||
.frequency_stepsize = 62500,
|
||||
.symbol_rate_min = 5056941,
|
||||
.symbol_rate_max = 10762000,
|
||||
.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
|
||||
},
|
||||
.init = lgdt3304_init,
|
||||
.sleep = lgdt3304_sleep,
|
||||
.set_frontend = lgdt3304_set_parameters,
|
||||
.read_snr = lgdt3304_read_snr,
|
||||
.read_ber = lgdt3304_read_ber,
|
||||
.read_status = lgdt3304_read_status,
|
||||
.read_ucblocks = lgdt3304_read_ucblocks,
|
||||
.release = lgdt3304_release,
|
||||
};
|
||||
|
||||
struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
|
||||
struct lgdt3304_state *state;
|
||||
state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
|
||||
if (state == NULL)
|
||||
return NULL;
|
||||
state->addr = config->i2c_address;
|
||||
state->i2c = i2c;
|
||||
|
||||
memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops));
|
||||
state->frontend.demodulator_priv = state;
|
||||
return &state->frontend;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(lgdt3304_attach);
|
||||
MODULE_AUTHOR("Markus Rechberger <[email protected]>");
|
||||
MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Driver for DVB-T lgdt3304 demodulator
|
||||
*
|
||||
* Copyright (C) 2008 Markus Rechberger <mrechberger@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
*
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
|
||||
*/
|
||||
|
||||
#ifndef LGDT3304_H
|
||||
#define LGDT3304_H
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct lgdt3304_config
|
||||
{
|
||||
/* demodulator's I2C address */
|
||||
u8 i2c_address;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_DVB_LGDT */
|
||||
|
||||
#endif /* LGDT3304_H */
|
||||
|
|
@ -662,7 +662,7 @@ static void lgs8gxx_release(struct dvb_frontend *fe)
|
|||
}
|
||||
|
||||
|
||||
static int lgs8gxx_write(struct dvb_frontend *fe, u8 *buf, int len)
|
||||
static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len)
|
||||
{
|
||||
struct lgs8gxx_state *priv = fe->demodulator_priv;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
|
||||
static int _mt352_write(struct dvb_frontend* fe, const u8 ibuf[], int ilen)
|
||||
{
|
||||
int err,i;
|
||||
for (i=0; i < ilen-1; i++)
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ static inline struct dvb_frontend* mt352_attach(const struct mt352_config* confi
|
|||
}
|
||||
#endif // CONFIG_DVB_MT352
|
||||
|
||||
static inline int mt352_write(struct dvb_frontend *fe, u8 *buf, int len) {
|
||||
static inline int mt352_write(struct dvb_frontend *fe, const u8 buf[], int len) {
|
||||
int r = 0;
|
||||
if (fe->ops.write)
|
||||
r = fe->ops.write(fe, buf, len);
|
||||
|
|
|
|||
|
|
@ -920,7 +920,6 @@ struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
|
|||
/* create tuner i2c adapter */
|
||||
strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
|
||||
sizeof(state->tuner_i2c_adapter.name));
|
||||
state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL,
|
||||
state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo;
|
||||
state->tuner_i2c_adapter.algo_data = NULL;
|
||||
i2c_set_adapdata(&state->tuner_i2c_adapter, state);
|
||||
|
|
|
|||
415
drivers/media/dvb/frontends/s5h1432.c
Normal file
415
drivers/media/dvb/frontends/s5h1432.c
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
* Samsung s5h1432 DVB-T demodulator driver
|
||||
*
|
||||
* Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include "dvb_frontend.h"
|
||||
#include "s5h1432.h"
|
||||
|
||||
struct s5h1432_state {
|
||||
|
||||
struct i2c_adapter *i2c;
|
||||
|
||||
/* configuration settings */
|
||||
const struct s5h1432_config *config;
|
||||
|
||||
struct dvb_frontend frontend;
|
||||
|
||||
fe_modulation_t current_modulation;
|
||||
unsigned int first_tune:1;
|
||||
|
||||
u32 current_frequency;
|
||||
int if_freq;
|
||||
|
||||
u8 inversion;
|
||||
};
|
||||
|
||||
static int debug;
|
||||
|
||||
#define dprintk(arg...) do { \
|
||||
if (debug) \
|
||||
printk(arg); \
|
||||
} while (0)
|
||||
|
||||
static int s5h1432_writereg(struct s5h1432_state *state,
|
||||
u8 addr, u8 reg, u8 data)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[] = { reg, data };
|
||||
|
||||
struct i2c_msg msg = {.addr = addr, .flags = 0, .buf = buf, .len = 2 };
|
||||
|
||||
ret = i2c_transfer(state->i2c, &msg, 1);
|
||||
|
||||
if (ret != 1)
|
||||
printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, "
|
||||
"ret == %i)\n", __func__, addr, reg, data, ret);
|
||||
|
||||
return (ret != 1) ? -1 : 0;
|
||||
}
|
||||
|
||||
static u8 s5h1432_readreg(struct s5h1432_state *state, u8 addr, u8 reg)
|
||||
{
|
||||
int ret;
|
||||
u8 b0[] = { reg };
|
||||
u8 b1[] = { 0 };
|
||||
|
||||
struct i2c_msg msg[] = {
|
||||
{.addr = addr, .flags = 0, .buf = b0, .len = 1},
|
||||
{.addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(state->i2c, msg, 2);
|
||||
|
||||
if (ret != 2)
|
||||
printk(KERN_ERR "%s: readreg error (ret == %i)\n",
|
||||
__func__, ret);
|
||||
return b1[0];
|
||||
}
|
||||
|
||||
static int s5h1432_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1432_set_channel_bandwidth(struct dvb_frontend *fe,
|
||||
u32 bandwidth)
|
||||
{
|
||||
struct s5h1432_state *state = fe->demodulator_priv;
|
||||
|
||||
u8 reg = 0;
|
||||
|
||||
/* Register [0x2E] bit 3:2 : 8MHz = 0; 7MHz = 1; 6MHz = 2 */
|
||||
reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x2E);
|
||||
reg &= ~(0x0C);
|
||||
switch (bandwidth) {
|
||||
case 6:
|
||||
reg |= 0x08;
|
||||
break;
|
||||
case 7:
|
||||
reg |= 0x04;
|
||||
break;
|
||||
case 8:
|
||||
reg |= 0x00;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2E, reg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s5h1432_set_IF(struct dvb_frontend *fe, u32 ifFreqHz)
|
||||
{
|
||||
struct s5h1432_state *state = fe->demodulator_priv;
|
||||
|
||||
switch (ifFreqHz) {
|
||||
case TAIWAN_HI_IF_FREQ_44_MHZ:
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x15);
|
||||
break;
|
||||
case EUROPE_HI_IF_FREQ_36_MHZ:
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x40);
|
||||
break;
|
||||
case IF_FREQ_6_MHZ:
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xe0);
|
||||
break;
|
||||
case IF_FREQ_3point3_MHZ:
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
|
||||
break;
|
||||
case IF_FREQ_3point5_MHZ:
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xED);
|
||||
break;
|
||||
case IF_FREQ_4_MHZ:
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0xAA);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0xAA);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEA);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
u32 value = 0;
|
||||
value = (u32) (((48000 - (ifFreqHz / 1000)) * 512 *
|
||||
(u32) 32768) / (48 * 1000));
|
||||
printk(KERN_INFO
|
||||
"Default IFFreq %d :reg value = 0x%x\n",
|
||||
ifFreqHz, value);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4,
|
||||
(u8) value & 0xFF);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5,
|
||||
(u8) (value >> 8) & 0xFF);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7,
|
||||
(u8) (value >> 16) & 0xFF);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
|
||||
static int s5h1432_set_frontend(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *p)
|
||||
{
|
||||
u32 dvb_bandwidth = 8;
|
||||
struct s5h1432_state *state = fe->demodulator_priv;
|
||||
|
||||
if (p->frequency == state->current_frequency) {
|
||||
/*current_frequency = p->frequency; */
|
||||
/*state->current_frequency = p->frequency; */
|
||||
} else {
|
||||
fe->ops.tuner_ops.set_params(fe, p);
|
||||
msleep(300);
|
||||
s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
|
||||
switch (p->u.ofdm.bandwidth) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
dvb_bandwidth = 6;
|
||||
s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
dvb_bandwidth = 7;
|
||||
s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
dvb_bandwidth = 8;
|
||||
s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
/*fe->ops.tuner_ops.set_params(fe, p); */
|
||||
/*Soft Reset chip*/
|
||||
msleep(30);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
|
||||
msleep(30);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
|
||||
|
||||
s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
|
||||
switch (p->u.ofdm.bandwidth) {
|
||||
case BANDWIDTH_6_MHZ:
|
||||
dvb_bandwidth = 6;
|
||||
s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
|
||||
break;
|
||||
case BANDWIDTH_7_MHZ:
|
||||
dvb_bandwidth = 7;
|
||||
s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
|
||||
break;
|
||||
case BANDWIDTH_8_MHZ:
|
||||
dvb_bandwidth = 8;
|
||||
s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
/*fe->ops.tuner_ops.set_params(fe,p); */
|
||||
/*Soft Reset chip*/
|
||||
msleep(30);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
|
||||
msleep(30);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
|
||||
|
||||
}
|
||||
|
||||
state->current_frequency = p->frequency;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1432_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct s5h1432_state *state = fe->demodulator_priv;
|
||||
|
||||
u8 reg = 0;
|
||||
state->current_frequency = 0;
|
||||
printk(KERN_INFO " s5h1432_init().\n");
|
||||
|
||||
/*Set VSB mode as default, this also does a soft reset */
|
||||
/*Initialize registers */
|
||||
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x04, 0xa8);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x05, 0x01);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x07, 0x70);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x19, 0x80);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1b, 0x9D);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1c, 0x30);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1d, 0x20);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x1B);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2e, 0x40);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, 0x84);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x50, 0x5a);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x5a, 0xd3);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x68, 0x50);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xb8, 0x3c);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xc4, 0x10);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xcc, 0x9c);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xDA, 0x00);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe1, 0x94);
|
||||
/* s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf4, 0xa1); */
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf9, 0x00);
|
||||
|
||||
/*For NXP tuner*/
|
||||
|
||||
/*Set 3.3MHz as default IF frequency */
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
|
||||
/* Set reg 0x1E to get the full dynamic range */
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x31);
|
||||
|
||||
/* Mode setting in demod */
|
||||
reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x42);
|
||||
reg |= 0x80;
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, reg);
|
||||
/* Serial mode */
|
||||
|
||||
/* Soft Reset chip */
|
||||
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
|
||||
msleep(30);
|
||||
s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1432_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1432_read_signal_strength(struct dvb_frontend *fe,
|
||||
u16 *signal_strength)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1432_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1432_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1432_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1432_get_frontend(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5h1432_get_tune_settings(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_tune_settings *tune)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void s5h1432_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct s5h1432_state *state = fe->demodulator_priv;
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops s5h1432_ops;
|
||||
|
||||
struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct s5h1432_state *state = NULL;
|
||||
|
||||
printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n");
|
||||
/* allocate memory for the internal state */
|
||||
state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL);
|
||||
if (state == NULL)
|
||||
goto error;
|
||||
|
||||
/* setup the state */
|
||||
state->config = config;
|
||||
state->i2c = i2c;
|
||||
state->current_modulation = QAM_16;
|
||||
state->inversion = state->config->inversion;
|
||||
|
||||
/* create dvb_frontend */
|
||||
memcpy(&state->frontend.ops, &s5h1432_ops,
|
||||
sizeof(struct dvb_frontend_ops));
|
||||
|
||||
state->frontend.demodulator_priv = state;
|
||||
|
||||
return &state->frontend;
|
||||
|
||||
error:
|
||||
kfree(state);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(s5h1432_attach);
|
||||
|
||||
static struct dvb_frontend_ops s5h1432_ops = {
|
||||
|
||||
.info = {
|
||||
.name = "Samsung s5h1432 DVB-T Frontend",
|
||||
.type = FE_OFDM,
|
||||
.frequency_min = 177000000,
|
||||
.frequency_max = 858000000,
|
||||
.frequency_stepsize = 166666,
|
||||
.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
|
||||
FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER},
|
||||
|
||||
.init = s5h1432_init,
|
||||
.sleep = s5h1432_sleep,
|
||||
.set_frontend = s5h1432_set_frontend,
|
||||
.get_frontend = s5h1432_get_frontend,
|
||||
.get_tune_settings = s5h1432_get_tune_settings,
|
||||
.read_status = s5h1432_read_status,
|
||||
.read_ber = s5h1432_read_ber,
|
||||
.read_signal_strength = s5h1432_read_signal_strength,
|
||||
.read_snr = s5h1432_read_snr,
|
||||
.read_ucblocks = s5h1432_read_ucblocks,
|
||||
.release = s5h1432_release,
|
||||
};
|
||||
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Enable verbose debug messages");
|
||||
|
||||
MODULE_DESCRIPTION("Samsung s5h1432 DVB-T Demodulator driver");
|
||||
MODULE_AUTHOR("Bill Liu");
|
||||
MODULE_LICENSE("GPL");
|
||||
91
drivers/media/dvb/frontends/s5h1432.h
Normal file
91
drivers/media/dvb/frontends/s5h1432.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Samsung s5h1432 VSB/QAM demodulator driver
|
||||
*
|
||||
* Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __S5H1432_H__
|
||||
#define __S5H1432_H__
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#define S5H1432_I2C_TOP_ADDR (0x02 >> 1)
|
||||
|
||||
#define TAIWAN_HI_IF_FREQ_44_MHZ 44000000
|
||||
#define EUROPE_HI_IF_FREQ_36_MHZ 36000000
|
||||
#define IF_FREQ_6_MHZ 6000000
|
||||
#define IF_FREQ_3point3_MHZ 3300000
|
||||
#define IF_FREQ_3point5_MHZ 3500000
|
||||
#define IF_FREQ_4_MHZ 4000000
|
||||
|
||||
struct s5h1432_config {
|
||||
|
||||
/* serial/parallel output */
|
||||
#define S5H1432_PARALLEL_OUTPUT 0
|
||||
#define S5H1432_SERIAL_OUTPUT 1
|
||||
u8 output_mode;
|
||||
|
||||
/* GPIO Setting */
|
||||
#define S5H1432_GPIO_OFF 0
|
||||
#define S5H1432_GPIO_ON 1
|
||||
u8 gpio;
|
||||
|
||||
/* MPEG signal timing */
|
||||
#define S5H1432_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0
|
||||
#define S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1
|
||||
#define S5H1432_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2
|
||||
#define S5H1432_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
|
||||
u16 mpeg_timing;
|
||||
|
||||
/* IF Freq for QAM and VSB in KHz */
|
||||
#define S5H1432_IF_3250 3250
|
||||
#define S5H1432_IF_3500 3500
|
||||
#define S5H1432_IF_4000 4000
|
||||
#define S5H1432_IF_5380 5380
|
||||
#define S5H1432_IF_44000 44000
|
||||
#define S5H1432_VSB_IF_DEFAULT s5h1432_IF_44000
|
||||
#define S5H1432_QAM_IF_DEFAULT s5h1432_IF_44000
|
||||
u16 qam_if;
|
||||
u16 vsb_if;
|
||||
|
||||
/* Spectral Inversion */
|
||||
#define S5H1432_INVERSION_OFF 0
|
||||
#define S5H1432_INVERSION_ON 1
|
||||
u8 inversion;
|
||||
|
||||
/* Return lock status based on tuner lock, or demod lock */
|
||||
#define S5H1432_TUNERLOCKING 0
|
||||
#define S5H1432_DEMODLOCKING 1
|
||||
u8 status_mode;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_S5H1432) || \
|
||||
(defined(CONFIG_DVB_S5H1432_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
static inline struct dvb_frontend *s5h1432_attach(const struct s5h1432_config
|
||||
*config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_DVB_s5h1432 */
|
||||
|
||||
#endif /* __s5h1432_H__ */
|
||||
|
|
@ -268,7 +268,7 @@ static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
|
|||
return (ret != 1) ? -EREMOTEIO : 0;
|
||||
}
|
||||
|
||||
static int si21_write(struct dvb_frontend *fe, u8 *buf, int len)
|
||||
static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
|
||||
{
|
||||
struct si21xx_state *state = fe->demodulator_priv;
|
||||
|
||||
|
|
|
|||
|
|
@ -506,7 +506,7 @@ static struct dvb_tuner_ops stb6100_ops = {
|
|||
};
|
||||
|
||||
struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
|
||||
struct stb6100_config *config,
|
||||
const struct stb6100_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct stb6100_state *state = NULL;
|
||||
|
|
|
|||
|
|
@ -97,13 +97,13 @@ struct stb6100_state {
|
|||
#if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
|
||||
struct stb6100_config *config,
|
||||
const struct stb6100_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
|
||||
struct stb6100_config *config,
|
||||
const struct stb6100_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
|
||||
Removed stb6000 specific tuner code and revised some
|
||||
procedures.
|
||||
2010-09-01 Josef Pavlik <josef@pavlik.it>
|
||||
Fixed diseqc_msg, diseqc_burst and set_tone problems
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -78,7 +80,7 @@ static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
|
|||
return (ret != 1) ? -EREMOTEIO : 0;
|
||||
}
|
||||
|
||||
static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len)
|
||||
static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len)
|
||||
{
|
||||
struct stv0288_state *state = fe->demodulator_priv;
|
||||
|
||||
|
|
@ -156,14 +158,13 @@ static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
|
|||
|
||||
stv0288_writeregI(state, 0x09, 0);
|
||||
msleep(30);
|
||||
stv0288_writeregI(state, 0x05, 0x16);
|
||||
stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */
|
||||
|
||||
for (i = 0; i < m->msg_len; i++) {
|
||||
if (stv0288_writeregI(state, 0x06, m->msg[i]))
|
||||
return -EREMOTEIO;
|
||||
msleep(12);
|
||||
}
|
||||
|
||||
msleep(m->msg_len*12);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -174,13 +175,14 @@ static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
|
|||
|
||||
dprintk("%s\n", __func__);
|
||||
|
||||
if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */
|
||||
if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */
|
||||
return -EREMOTEIO;
|
||||
|
||||
if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
|
||||
return -EREMOTEIO;
|
||||
|
||||
if (stv0288_writeregI(state, 0x06, 0x12))
|
||||
msleep(15);
|
||||
if (stv0288_writeregI(state, 0x05, 0x12))
|
||||
return -EREMOTEIO;
|
||||
|
||||
return 0;
|
||||
|
|
@ -192,18 +194,19 @@ static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
|
|||
|
||||
switch (tone) {
|
||||
case SEC_TONE_ON:
|
||||
if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */
|
||||
if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */
|
||||
return -EREMOTEIO;
|
||||
return stv0288_writeregI(state, 0x06, 0xff);
|
||||
break;
|
||||
|
||||
case SEC_TONE_OFF:
|
||||
if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */
|
||||
if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/
|
||||
return -EREMOTEIO;
|
||||
return stv0288_writeregI(state, 0x06, 0x00);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 stv0288_inittab[] = {
|
||||
|
|
@ -486,7 +489,7 @@ static int stv0288_set_frontend(struct dvb_frontend *fe,
|
|||
tda[2] = 0x0; /* CFRL */
|
||||
for (tm = -6; tm < 7;) {
|
||||
/* Viterbi status */
|
||||
if (stv0288_readreg(state, 0x24) & 0x80)
|
||||
if (stv0288_readreg(state, 0x24) & 0x8)
|
||||
break;
|
||||
|
||||
tda[2] += 40;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
|
|||
return (ret != 1) ? -EREMOTEIO : 0;
|
||||
}
|
||||
|
||||
static int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len)
|
||||
static int stv0299_write(struct dvb_frontend* fe, const u8 buf[], int len)
|
||||
{
|
||||
struct stv0299_state* state = fe->demodulator_priv;
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ struct stv0299_config
|
|||
* First of each pair is the register, second is the value.
|
||||
* List should be terminated with an 0xff, 0xff pair.
|
||||
*/
|
||||
u8* inittab;
|
||||
const u8* inittab;
|
||||
|
||||
/* master clock to use */
|
||||
u32 mclk;
|
||||
|
|
|
|||
|
|
@ -598,7 +598,7 @@ static int tda1004x_decode_fec(int tdafec)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len)
|
||||
static int tda1004x_write(struct dvb_frontend* fe, const u8 buf[], int len)
|
||||
{
|
||||
struct tda1004x_state* state = fe->demodulator_priv;
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue