LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Pavel Machek <pavel@suse.cz>
To: Jon Smirl <jonsmirl@gmail.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH V4 1/6] Minimal changes to the core input system
Date: Wed, 5 Nov 2008 22:38:28 +0100	[thread overview]
Message-ID: <20081105213828.GA3966@elf.ucw.cz> (raw)
In-Reply-To: <20081105194738.19407.31117.stgit@localhost>

On Wed 2008-11-05 14:47:38, Jon Smirl wrote:
> Minimal changes to the core input system. The bulk of IR support loads as a module. These changes are passive if the rest of IR isn't loaded.
> 
> Jon Smirl
> <jonsmirl@gmail.com>

Apart from too long lines in changelog and missed Signed-off-by: it
looks okay to me ;-).

> ---
>  drivers/input/evdev.c           |   55 +++++++++++++++++++++++++++++
>  drivers/input/input.c           |   17 +++++++++
>  include/linux/input.h           |   75 +++++++++++++++++++++++++++++++++++++++
>  include/linux/mod_devicetable.h |    3 ++
>  4 files changed, 150 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
> index 1070db3..33a01dc 100644
> --- a/drivers/input/evdev.c
> +++ b/drivers/input/evdev.c
> @@ -328,6 +328,14 @@ struct ff_effect_compat {
>  	} u;
>  };
>  
> +struct ir_command_compat {
> +	__u32 protocol;
> +	__u32 device;
> +	__u32 command;
> +	__u32 transmitters;
> +};
> +
> +
>  /* Note to the author of this code: did it ever occur to
>     you why the ifdefs are needed? Think about it again. -AK */
>  #ifdef CONFIG_X86_64
> @@ -432,6 +440,32 @@ static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
>  	return 0;
>  }
>  
> +static int evdev_ir_send_from_user(const char __user *buffer, size_t size,
> +				     struct ir_command *ir_command)
> +{
> +	if (COMPAT_TEST) {
> +		struct ir_command_compat *compat_ir_command;
> +
> +		if (size != sizeof(struct ir_command_compat))
> +			return -EINVAL;
> +
> +		compat_ir_command = (struct ir_command_compat *)ir_command;
> +
> +		if (copy_from_user(compat_ir_command, buffer,
> +				   sizeof(struct ir_command_compat)))
> +			return -EFAULT;
> +
> +	} else {
> +		if (size != sizeof(struct ir_command))
> +			return -EINVAL;
> +
> +		if (copy_from_user(ir_command, buffer, sizeof(struct ir_command)))
> +			return -EFAULT;
> +	}
> +
> +	return 0;
> +}
> +
>  #else
>  
>  static inline size_t evdev_event_size(void)
> @@ -469,6 +503,18 @@ static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
>  	return 0;
>  }
>  
> +static int evdev_ir_send_from_user(const char __user *buffer, size_t size,
> +				     struct ir_command *ir_command)
> +{
> +	if (size != sizeof(struct ir_command))
> +		return -EINVAL;
> +
> +	if (copy_from_user(ir_command, buffer, sizeof(struct ir_command)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
>  #endif /* CONFIG_COMPAT */
>  
>  static ssize_t evdev_write(struct file *file, const char __user *buffer,
> @@ -695,6 +741,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
>  	struct input_dev *dev = evdev->handle.dev;
>  	struct input_absinfo abs;
>  	struct ff_effect effect;
> +	struct ir_command ir_command;
>  	int __user *ip = (int __user *)p;
>  	int i, t, u, v;
>  	int error;
> @@ -859,6 +906,14 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
>  
>  				return 0;
>  			}
> +
> +			if (_IOC_NR(cmd) == _IOC_NR(EVIOIRSEND)) {
> +
> +				if (evdev_ir_send_from_user(p, _IOC_SIZE(cmd), &ir_command))
> +					return -EFAULT;
> +
> +				return input_ir_send(dev, &ir_command, file);
> +			}
>  		}
>  	}
>  	return -EINVAL;
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index c13ced3..0a9b15a 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -240,6 +240,10 @@ static void input_handle_event(struct input_dev *dev,
>  	case EV_PWR:
>  		disposition = INPUT_PASS_TO_ALL;
>  		break;
> +
> +	case EV_IR:
> +		disposition = INPUT_PASS_TO_ALL;
> +		break;
>  	}
>  
>  	if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
> @@ -693,6 +697,7 @@ static const struct input_device_id *input_match_device(const struct input_devic
>  		MATCH_BIT(sndbit, SND_MAX);
>  		MATCH_BIT(ffbit,  FF_MAX);
>  		MATCH_BIT(swbit,  SW_MAX);
> +		MATCH_BIT(irbit,  IR_MAX);
>  
>  		return id;
>  	}
> @@ -815,6 +820,8 @@ static int input_devices_seq_show(struct seq_file *seq, void *v)
>  		input_seq_print_bitmap(seq, "FF", dev->ffbit, FF_MAX);
>  	if (test_bit(EV_SW, dev->evbit))
>  		input_seq_print_bitmap(seq, "SW", dev->swbit, SW_MAX);
> +	if (test_bit(EV_IR, dev->evbit))
> +		input_seq_print_bitmap(seq, "IR", dev->irbit, IR_MAX);
>  
>  	seq_putc(seq, '\n');
>  
> @@ -992,6 +999,8 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id,
>  				'f', id->ffbit, 0, FF_MAX);
>  	len += input_print_modalias_bits(buf + len, size - len,
>  				'w', id->swbit, 0, SW_MAX);
> +	len += input_print_modalias_bits(buf + len, size - len,
> +				'i', id->irbit, 0, IR_MAX);
>  
>  	if (add_cr)
>  		len += snprintf(buf + len, max(size - len, 0), "\n");
> @@ -1093,6 +1102,7 @@ INPUT_DEV_CAP_ATTR(LED, led);
>  INPUT_DEV_CAP_ATTR(SND, snd);
>  INPUT_DEV_CAP_ATTR(FF, ff);
>  INPUT_DEV_CAP_ATTR(SW, sw);
> +INPUT_DEV_CAP_ATTR(IR, ir);
>  
>  static struct attribute *input_dev_caps_attrs[] = {
>  	&dev_attr_ev.attr,
> @@ -1104,6 +1114,7 @@ static struct attribute *input_dev_caps_attrs[] = {
>  	&dev_attr_snd.attr,
>  	&dev_attr_ff.attr,
>  	&dev_attr_sw.attr,
> +	&dev_attr_ir.attr,
>  	NULL
>  };
>  
> @@ -1221,6 +1232,8 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
>  		INPUT_ADD_HOTPLUG_BM_VAR("FF=", dev->ffbit, FF_MAX);
>  	if (test_bit(EV_SW, dev->evbit))
>  		INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);
> +	if (test_bit(EV_IR, dev->evbit))
> +		INPUT_ADD_HOTPLUG_BM_VAR("IR=", dev->irbit, IR_MAX);
>  
>  	INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev);
>  
> @@ -1333,6 +1346,10 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int
>  		__set_bit(code, dev->ffbit);
>  		break;
>  
> +	case EV_IR:
> +		__set_bit(code, dev->irbit);
> +		break;
> +
>  	case EV_PWR:
>  		/* do nothing */
>  		break;
> diff --git a/include/linux/input.h b/include/linux/input.h
> index b86fb55..95e385f 100644
> --- a/include/linux/input.h
> +++ b/include/linux/input.h
> @@ -79,6 +79,8 @@ struct input_absinfo {
>  #define EVIOCRMFF		_IOW('E', 0x81, int)			/* Erase a force effect */
>  #define EVIOCGEFFECTS		_IOR('E', 0x84, int)			/* Report number of effects playable at the same time */
>  
> +#define EVIOIRSEND		_IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ir_command))	/* send an IR command */
> +
>  #define EVIOCGRAB		_IOW('E', 0x90, int)			/* Grab/Release device */
>  
>  /*
> @@ -97,6 +99,7 @@ struct input_absinfo {
>  #define EV_FF			0x15
>  #define EV_PWR			0x16
>  #define EV_FF_STATUS		0x17
> +#define EV_IR			0x18
>  #define EV_MAX			0x1f
>  #define EV_CNT			(EV_MAX+1)
>  
> @@ -959,6 +962,56 @@ struct ff_effect {
>  #define FF_MAX		0x7f
>  #define FF_CNT		(FF_MAX+1)
>  
> +/*
> + * IR Support
> + */
> +
> +#define IR_PROTOCOL_RESERVED 0
> +#define IR_PROTOCOL_JVC 1
> +#define IR_PROTOCOL_NEC 2
> +#define IR_PROTOCOL_NOKIA 3
> +#define IR_PROTOCOL_SHARP 4
> +#define IR_PROTOCOL_SONY_12 5
> +#define IR_PROTOCOL_SONY_15 6
> +#define IR_PROTOCOL_SONY_20 7
> +#define IR_PROTOCOL_PHILIPS_RC5 8
> +#define IR_PROTOCOL_PHILIPS_RC6 9
> +#define IR_PROTOCOL_PHILIPS_RCMM 10
> +#define IR_PROTOCOL_PHILIPS_RECS80 11
> +#define IR_PROTOCOL_RCA 12
> +#define IR_PROTOCOL_ITT 13
> +
> +#define IR_PROTOCOL 1
> +#define IR_DEVICE 2
> +#define IR_COMMAND 3
> +
> +#define IR_CAP_RECEIVE_BASEBAND 0
> +#define IR_CAP_RECEIVE_36K 1
> +#define IR_CAP_RECEIVE_38K 2
> +#define IR_CAP_RECEIVE_40K 3
> +#define IR_CAP_RECEIVE_56K 4
> +#define IR_CAP_SEND_BASEBAND 5
> +#define IR_CAP_SEND_36K 6
> +#define IR_CAP_SEND_38K 7
> +#define IR_CAP_SEND_40K 8
> +#define IR_CAP_SEND_56K 9
> +#define IR_CAP_XMITTER_1 10
> +#define IR_CAP_XMITTER_2 11
> +#define IR_CAP_XMITTER_3 12
> +#define IR_CAP_XMITTER_4 13
> +#define IR_CAP_RECEIVE_RAW 14
> +#define IR_CAP_SEND_RAW 15
> +#define IR_MAX 0x0f
> +#define IR_CNT IR_MAX + 1
> +
> +struct ir_command {
> +	__u32 protocol;
> +	__u32 device;
> +	__u32 command;
> +	__u32 transmitters;
> +};
> +
> +
>  #ifdef __KERNEL__
>  
>  /*
> @@ -986,6 +1039,7 @@ struct ff_effect {
>   * @sndbit: bitmap of sound effects supported by the device
>   * @ffbit: bitmap of force feedback effects supported by the device
>   * @swbit: bitmap of switches present on the device
> + * @irbit: bitmap of capabilies of the IR hardware
>   * @keycodemax: size of keycode table
>   * @keycodesize: size of elements in keycode table
>   * @keycode: map of scancodes to keycodes for this device
> @@ -1058,6 +1112,7 @@ struct input_dev {
>  	unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
>  	unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
>  	unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
> +	unsigned long irbit[BITS_TO_LONGS(IR_CNT)];
>  
>  	unsigned int keycodemax;
>  	unsigned int keycodesize;
> @@ -1066,6 +1121,7 @@ struct input_dev {
>  	int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);
>  
>  	struct ff_device *ff;
> +	struct ir_device *ir;
>  
>  	unsigned int repeat_key;
>  	struct timer_list timer;
> @@ -1301,6 +1357,11 @@ static inline void input_report_switch(struct input_dev *dev, unsigned int code,
>  	input_event(dev, EV_SW, code, !!value);
>  }
>  
> +static inline void input_report_ir(struct input_dev *dev, unsigned int code, int value)
> +{
> +	input_event(dev, EV_IR, code, value);
> +}
> +
>  static inline void input_sync(struct input_dev *dev)
>  {
>  	input_event(dev, EV_SYN, SYN_REPORT, 0);
> @@ -1379,5 +1440,19 @@ int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
>  int input_ff_create_memless(struct input_dev *dev, void *data,
>  		int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
>  
> +/**
> + * IR support functions
> + */
> +
> +typedef int (*send_func)(void *private, unsigned int *buffer, unsigned int count,
> +		unsigned int frequency, unsigned int xmitters);
> +
> +int input_ir_create(struct input_dev *dev, void *private, send_func send);
> +void input_ir_destroy(struct input_dev *dev);
> +
> +void input_ir_decode(struct input_dev *dev, unsigned int delta, unsigned int bit);
> +int input_ir_send(struct input_dev *dev, struct ir_command *ir_command, struct file *file);
> +int input_ir_register(struct input_dev *dev);
> +
>  #endif
>  #endif
> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 97b91d1..ea35367 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -293,6 +293,7 @@ struct pcmcia_device_id {
>  #define INPUT_DEVICE_ID_SND_MAX		0x07
>  #define INPUT_DEVICE_ID_FF_MAX		0x7f
>  #define INPUT_DEVICE_ID_SW_MAX		0x0f
> +#define INPUT_DEVICE_ID_IR_MAX		0x0f
>  
>  #define INPUT_DEVICE_ID_MATCH_BUS	1
>  #define INPUT_DEVICE_ID_MATCH_VENDOR	2
> @@ -308,6 +309,7 @@ struct pcmcia_device_id {
>  #define INPUT_DEVICE_ID_MATCH_SNDBIT	0x0400
>  #define INPUT_DEVICE_ID_MATCH_FFBIT	0x0800
>  #define INPUT_DEVICE_ID_MATCH_SWBIT	0x1000
> +#define INPUT_DEVICE_ID_MATCH_IRBIT	0x2000
>  
>  struct input_device_id {
>  
> @@ -327,6 +329,7 @@ struct input_device_id {
>  	kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1];
>  	kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1];
>  	kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1];
> +	kernel_ulong_t irbit[INPUT_DEVICE_ID_IR_MAX / BITS_PER_LONG + 1];
>  
>  	kernel_ulong_t driver_info;
>  };
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

  reply	other threads:[~2008-11-05 21:37 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-05 19:47 [RFC PATCH V4 0/6] In-kernel IR remote control support Jon Smirl
2008-11-05 19:47 ` [RFC PATCH V4 1/6] Minimal changes to the core input system Jon Smirl
2008-11-05 21:38   ` Pavel Machek [this message]
2008-11-05 21:51     ` Jon Smirl
2008-11-05 19:47 ` [RFC PATCH V4 2/6] Core IR module Jon Smirl
2008-11-05 19:47 ` [RFC PATCH V4 3/6] Configfs support for IR Jon Smirl
2008-11-05 21:41   ` Pavel Machek
2008-11-05 21:51     ` Jon Smirl
2008-11-05 19:47 ` [RFC PATCH V4 4/6] GPT driver for in-kernel IR support Jon Smirl
2008-11-05 19:47 ` [RFC PATCH V4 5/6] Example of PowerPC device tree support for GPT based IR Jon Smirl
2008-11-05 19:47 ` [RFC PATCH V4 6/6] Microsoft mceusb2 driver for in-kernel IR subsystem Jon Smirl
2008-11-05 19:59 ` [RFC PATCH V4 0/6] In-kernel IR remote control support J.R. Mauro
2008-11-05 20:07   ` Jon Smirl
2008-11-05 20:15     ` J.R. Mauro
2008-11-05 20:47       ` Jon Smirl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081105213828.GA3966@elf.ucw.cz \
    --to=pavel@suse.cz \
    --cc=jonsmirl@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --subject='Re: [RFC PATCH V4 1/6] Minimal changes to the core input system' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).