All of 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 \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.