Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 202168
b: refs/heads/master
c: 844a9e9
h: refs/heads/master
v: v3
  • Loading branch information
Mauro Carvalho Chehab committed Aug 2, 2010
1 parent 819c226 commit 875aeda
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 278 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1722f3b376f10182db85c2f6cf5bd79b857bc9e0
refs/heads/master: 844a9e93d7fcd910cd94f6eb262e2cc43cacbe56
5 changes: 3 additions & 2 deletions trunk/drivers/media/IR/ir-keytable.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,9 @@ int __ir_input_register(struct input_dev *input_dev,
goto out_event;
}

IR_dprintk(1, "Registered input device on %s for %s remote.\n",
driver_name, rc_tab->name);
IR_dprintk(1, "Registered input device on %s for %s remote%s.\n",
driver_name, rc_tab->name,
ir_dev->props->driver_type == RC_DRIVER_IR_RAW ? " in raw mode" : "");

return 0;

Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/media/dvb/siano/sms-cards.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ static struct sms_board sms_boards[] = {
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
.rc_codes = RC_MAP_RC5_HAUPPAUGE_NEW,
.board_cfg.leds_power = 26,
.board_cfg.led0 = 27,
.board_cfg.led1 = 28,
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/media/dvb/siano/sms-cards.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct sms_board {
enum sms_device_type_st type;
char *name, *fw[DEVICE_MODE_MAX];
struct sms_board_gpio_cfg board_cfg;
enum ir_kb_type ir_kb_type;
char *rc_codes; /* Name of IR codes table */

/* gpios */
int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
Expand Down
254 changes: 30 additions & 224 deletions trunk/drivers/media/dvb/siano/smsir.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
MDTV receiver kernel modules.
Copyright (C) 2006-2009, Uri Shkolnik
Copyright (c) 2010 - Mauro Carvalho Chehab
- Ported the driver to use rc-core
- IR raw event decoding is now done at rc-core
- Code almost re-written
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
Expand All @@ -22,227 +27,27 @@

#include <linux/types.h>
#include <linux/input.h>
#include <media/ir-core.h>

#include "smscoreapi.h"
#include "smsir.h"
#include "sms-cards.h"

/* In order to add new IR remote control -
* 1) Add it to the <enum ir_kb_type> @ smsir,h,
* 2) Add its map to keyboard_layout_maps below
* 3) Set your board (sms-cards sub-module) to use it
*/

static struct keyboard_layout_map_t keyboard_layout_maps[] = {
[SMS_IR_KB_DEFAULT_TV] = {
.ir_protocol = IR_RC5,
.rc5_kbd_address = KEYBOARD_ADDRESS_TV1,
.keyboard_layout_map = {
KEY_0, KEY_1, KEY_2,
KEY_3, KEY_4, KEY_5,
KEY_6, KEY_7, KEY_8,
KEY_9, 0, 0, KEY_POWER,
KEY_MUTE, 0, 0,
KEY_VOLUMEUP, KEY_VOLUMEDOWN,
KEY_BRIGHTNESSUP,
KEY_BRIGHTNESSDOWN, KEY_CHANNELUP,
KEY_CHANNELDOWN,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}
},
[SMS_IR_KB_HCW_SILVER] = {
.ir_protocol = IR_RC5,
.rc5_kbd_address = KEYBOARD_ADDRESS_LIGHTING1,
.keyboard_layout_map = {
KEY_0, KEY_1, KEY_2,
KEY_3, KEY_4, KEY_5,
KEY_6, KEY_7, KEY_8,
KEY_9, KEY_TEXT, KEY_RED,
KEY_RADIO, KEY_MENU,
KEY_SUBTITLE,
KEY_MUTE, KEY_VOLUMEUP,
KEY_VOLUMEDOWN, KEY_PREVIOUS, 0,
KEY_UP, KEY_DOWN, KEY_LEFT,
KEY_RIGHT, KEY_VIDEO, KEY_AUDIO,
KEY_MHP, KEY_EPG, KEY_TV,
0, KEY_NEXTSONG, KEY_EXIT,
KEY_CHANNELUP, KEY_CHANNELDOWN,
KEY_CHANNEL, 0,
KEY_PREVIOUSSONG, KEY_ENTER,
KEY_SLEEP, 0, 0, KEY_BLUE,
0, 0, 0, 0, KEY_GREEN, 0,
KEY_PAUSE, 0, KEY_REWIND,
0, KEY_FASTFORWARD, KEY_PLAY,
KEY_STOP, KEY_RECORD,
KEY_YELLOW, 0, 0, KEY_SELECT,
KEY_ZOOM, KEY_POWER, 0, 0
}
},
{ } /* Terminating entry */
};

static u32 ir_pos;
static u32 ir_word;
static u32 ir_toggle;

#define RC5_PUSH_BIT(dst, bit, pos) \
{ dst <<= 1; dst |= bit; pos++; }


static void sms_ir_rc5_event(struct smscore_device_t *coredev,
u32 toggle, u32 addr, u32 cmd)
{
bool toggle_changed;
u16 keycode;

sms_log("IR RC5 word: address %d, command %d, toggle %d",
addr, cmd, toggle);

toggle_changed = ir_toggle != toggle;
/* keep toggle */
ir_toggle = toggle;

if (addr !=
keyboard_layout_maps[coredev->ir.ir_kb_type].rc5_kbd_address)
return; /* Check for valid address */
#define MODULE_NAME "smsmdtv"

keycode =
keyboard_layout_maps
[coredev->ir.ir_kb_type].keyboard_layout_map[cmd];

if (!toggle_changed &&
(keycode != KEY_VOLUMEUP && keycode != KEY_VOLUMEDOWN))
return; /* accept only repeated volume, reject other keys */

sms_log("kernel input keycode (from ir) %d", keycode);
input_report_key(coredev->ir.input_dev, keycode, 1);
input_sync(coredev->ir.input_dev);

}

/* decode raw bit pattern to RC5 code */
/* taken from ir-functions.c */
static u32 ir_rc5_decode(unsigned int code)
void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
{
/* unsigned int org_code = code;*/
unsigned int pair;
unsigned int rc5 = 0;
int i;
const s32 *samples = (const void *)buf;

for (i = 0; i < 14; ++i) {
pair = code & 0x3;
code >>= 2;

rc5 <<= 1;
switch (pair) {
case 0:
case 2:
break;
case 1:
rc5 |= 1;
break;
case 3:
/* dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);*/
sms_log("bad code");
return 0;
}
}
/*
dprintk(1, "ir-common: code=%x, rc5=%x, start=%x,
toggle=%x, address=%x, "
"instr=%x\n", rc5, org_code, RC5_START(rc5),
RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
*/
return rc5;
}

static void sms_rc5_parse_word(struct smscore_device_t *coredev)
{
#define RC5_START(x) (((x)>>12)&3)
#define RC5_TOGGLE(x) (((x)>>11)&1)
#define RC5_ADDR(x) (((x)>>6)&0x1F)
#define RC5_INSTR(x) ((x)&0x3F)

int i, j;
u32 rc5_word = 0;

/* Reverse the IR word direction */
for (i = 0 ; i < 28 ; i++)
RC5_PUSH_BIT(rc5_word, (ir_word>>i)&1, j)

rc5_word = ir_rc5_decode(rc5_word);
/* sms_log("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */

sms_ir_rc5_event(coredev,
RC5_TOGGLE(rc5_word),
RC5_ADDR(rc5_word),
RC5_INSTR(rc5_word));
}


static void sms_rc5_accumulate_bits(struct smscore_device_t *coredev,
s32 ir_sample)
{
#define RC5_TIME_GRANULARITY 200
#define RC5_DEF_BIT_TIME 889
#define RC5_MAX_SAME_BIT_CONT 4
#define RC5_WORD_LEN 27 /* 28 bit */

u32 i, j;
s32 delta_time;
u32 time = (ir_sample > 0) ? ir_sample : (0-ir_sample);
u32 level = (ir_sample < 0) ? 0 : 1;
for (i = 0; i < len >> 2; i++) {
struct ir_raw_event ev;

for (i = RC5_MAX_SAME_BIT_CONT; i > 0; i--) {
delta_time = time - (i*RC5_DEF_BIT_TIME) + RC5_TIME_GRANULARITY;
if (delta_time < 0)
continue; /* not so many consecutive bits */
if (delta_time > (2 * RC5_TIME_GRANULARITY)) {
/* timeout */
if (ir_pos == (RC5_WORD_LEN-1))
/* complete last bit */
RC5_PUSH_BIT(ir_word, level, ir_pos)
ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
ev.pulse = (samples[i] > 0) ? false : true;

if (ir_pos == RC5_WORD_LEN)
sms_rc5_parse_word(coredev);
else if (ir_pos) /* timeout within a word */
sms_log("IR error parsing a word");

ir_pos = 0;
ir_word = 0;
/* sms_log("timeout %d", time); */
break;
}
/* The time is within the range of this number of bits */
for (j = 0 ; j < i ; j++)
RC5_PUSH_BIT(ir_word, level, ir_pos)

break;
ir_raw_event_store(coredev->ir.input_dev, &ev);
}
}

void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
{
#define IR_DATA_RECEIVE_MAX_LEN 520 /* 128*4 + 4 + 4 */
u32 i;
enum ir_protocol ir_protocol =
keyboard_layout_maps[coredev->ir.ir_kb_type]
.ir_protocol;
s32 *samples;
int count = len>>2;

samples = (s32 *)buf;
/* sms_log("IR buffer received, length = %d", count);*/

for (i = 0; i < count; i++)
if (ir_protocol == IR_RC5)
sms_rc5_accumulate_bits(coredev, samples[i]);
/* IR_RCMM not implemented */
ir_raw_event_handle(coredev->ir.input_dev);
}

int sms_ir_init(struct smscore_device_t *coredev)
Expand All @@ -258,21 +63,14 @@ int sms_ir_init(struct smscore_device_t *coredev)
}

coredev->ir.input_dev = input_dev;
coredev->ir.ir_kb_type = sms_get_board(board_id)->ir_kb_type;
coredev->ir.keyboard_layout_map =
keyboard_layout_maps[coredev->ir.ir_kb_type].
keyboard_layout_map;
sms_log("IR remote keyboard type is %d", coredev->ir.ir_kb_type);

coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
sms_log("IR port %d, timeout %d ms",
coredev->ir.controller, coredev->ir.timeout);

snprintf(coredev->ir.name,
sizeof(coredev->ir.name),
"SMS IR (%s)",
sms_get_board(board_id)->name);
snprintf(coredev->ir.name, sizeof(coredev->ir.name),
"SMS IR (%s)", sms_get_board(board_id)->name);

strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
Expand All @@ -281,13 +79,22 @@ int sms_ir_init(struct smscore_device_t *coredev)
input_dev->phys = coredev->ir.phys;
input_dev->dev.parent = coredev->device;

/* Key press events only */
input_dev->evbit[0] = BIT_MASK(EV_KEY);
input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
#if 0
/* TODO: properly initialize the parameters bellow */
input_dev->id.bustype = BUS_USB;
input_dev->id.version = 1;
input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
#endif

coredev->ir.props.priv = coredev;
coredev->ir.props.driver_type = RC_DRIVER_IR_RAW;
coredev->ir.props.allowed_protos = IR_TYPE_ALL;

sms_log("Input device (IR) %s is set for key events", input_dev->name);

if (input_register_device(input_dev)) {
if (ir_input_register(input_dev, sms_get_board(board_id)->rc_codes,
&coredev->ir.props, MODULE_NAME)) {
sms_err("Failed to register device");
input_free_device(input_dev);
return -EACCES;
Expand All @@ -299,8 +106,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
void sms_ir_exit(struct smscore_device_t *coredev)
{
if (coredev->ir.input_dev)
input_unregister_device(coredev->ir.input_dev);
ir_input_unregister(coredev->ir.input_dev);

sms_log("");
}

Loading

0 comments on commit 875aeda

Please sign in to comment.