From patchwork Wed Jul 28 15:14:07 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 114823 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6SFEfWL017912 for ; Wed, 28 Jul 2010 15:14:45 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754941Ab0G1POn (ORCPT ); Wed, 28 Jul 2010 11:14:43 -0400 Received: from mail-bw0-f46.google.com ([209.85.214.46]:59260 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754927Ab0G1POm (ORCPT ); Wed, 28 Jul 2010 11:14:42 -0400 Received: by mail-bw0-f46.google.com with SMTP id 1so4014228bwz.19 for ; Wed, 28 Jul 2010 08:14:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=xKanEoiy+NAQVe8NwZILVr+yK7x2cfUlehmKVtex5vA=; b=YxlBuJfe1LbUWEqaXjTc9bEC0kZBTf/PSCG0j0u7prhO4HefsIAT3mustR8V53bHDP AaytWaHMvcS70BE0uDvjtXxyGJYm9mTkfLUR8ajfSk/FzbVTPsFF/dgcAiFsDQgX45BF 8Dy9QkBSBLjGm4uTYUYyBf/g4L1GdImsi953M= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=oZzP0zhM5sh6clpbiAWEHvRzYYMQo/hItYDyUQVzT6kapILEy5zPcz06MJn3s+OXHS dk3mFfAXF+txq6muNQ4JLq+UsCETbOPNkwYnqsKQGQU8pR0Ik+vRXJu/UPcgjbCYL8l9 swf5Ja7c6sSkmBIQEqB9M/upM3Qt3jexLHbMc= Received: by 10.204.178.66 with SMTP id bl2mr7480049bkb.179.1280330078794; Wed, 28 Jul 2010 08:14:38 -0700 (PDT) Received: from localhost.localdomain (IGLD-84-229-112-176.inter.net.il [84.229.112.176]) by mx.google.com with ESMTPS id bq20sm4855282bkb.16.2010.07.28.08.14.36 (version=SSLv3 cipher=RC4-MD5); Wed, 28 Jul 2010 08:14:37 -0700 (PDT) From: Maxim Levitsky To: lirc-list@lists.sourceforge.net Cc: Jarod Wilson , linux-input@vger.kernel.org, linux-media@vger.kernel.org, Mauro Carvalho Chehab , Maxim Levitsky Subject: [PATCH 5/9] IR: extend interfaces to support more device settings Date: Wed, 28 Jul 2010 18:14:07 +0300 Message-Id: <1280330051-27732-6-git-send-email-maximlevitsky@gmail.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1280330051-27732-1-git-send-email-maximlevitsky@gmail.com> References: <1280330051-27732-1-git-send-email-maximlevitsky@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 28 Jul 2010 15:14:46 +0000 (UTC) diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index 3eafdb7..4ed170d 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h @@ -77,6 +77,8 @@ struct ir_raw_event_ctrl { struct lirc_codec { struct ir_input_dev *ir_dev; struct lirc_driver *drv; + int timeout_report; + int carrier_low; } lirc; }; diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 8ca01fd..0f3969c 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c @@ -96,13 +96,13 @@ out: return ret; } -static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) +static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long __user arg) { struct lirc_codec *lirc; struct ir_input_dev *ir_dev; int ret = 0; void *drv_data; - unsigned long val; + unsigned long val = 0; lirc = lirc_get_pdata(filep); if (!lirc) @@ -116,10 +116,21 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long ar switch (cmd) { case LIRC_SET_TRANSMITTER_MASK: + case LIRC_SET_SEND_CARRIER: + case LIRC_SET_SEND_MODE: + case LIRC_SET_REC_TIMEOUT: + case LIRC_SET_REC_TIMEOUT_REPORTS: + case LIRC_SET_LEARN_MODE: + case LIRC_SET_REC_CARRIER: + case LIRC_SET_REC_CARRIER_RANGE: + case LIRC_SET_SEND_DUTY_CYCLE: ret = get_user(val, (unsigned long *)arg); if (ret) return ret; + } + switch (cmd) { + case LIRC_SET_TRANSMITTER_MASK: if (ir_dev->props && ir_dev->props->s_tx_mask) ret = ir_dev->props->s_tx_mask(drv_data, (u32)val); else @@ -127,10 +138,6 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long ar break; case LIRC_SET_SEND_CARRIER: - ret = get_user(val, (unsigned long *)arg); - if (ret) - return ret; - if (ir_dev->props && ir_dev->props->s_tx_carrier) ir_dev->props->s_tx_carrier(drv_data, (u32)val); else @@ -143,14 +150,75 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long ar break; case LIRC_SET_SEND_MODE: - ret = get_user(val, (unsigned long *)arg); - if (ret) - return ret; - if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) return -EINVAL; break; + case LIRC_GET_REC_RESOLUTION: + val = ir_dev->props->rx_resolution; + ret = put_user(val, (unsigned long *)arg); + 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; + break; + + case LIRC_SET_REC_TIMEOUT_REPORTS: + ir_dev->raw->lirc.timeout_report = !!val; + return 0; + + case LIRC_GET_MIN_TIMEOUT: + + if (!ir_dev->props->max_timeout) + return -ENOSYS; + + ret = put_user(ir_dev->props->min_timeout, (unsigned long *)arg); + break; + case LIRC_GET_MAX_TIMEOUT: + if (!ir_dev->props->max_timeout) + return -ENOSYS; + + ret = put_user(ir_dev->props->max_timeout, (unsigned long *)arg); + break; + + case LIRC_SET_LEARN_MODE: + if (ir_dev->props->s_learning_mode) + return ir_dev->props->s_learning_mode( + ir_dev->props->priv, !!val); + else + return -ENOSYS; + + 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 + return -ENOSYS; + + if (!ret) + ir_dev->raw->lirc.carrier_low = 0; + break; + + case LIRC_SET_REC_CARRIER_RANGE: + if (val >= 0) + ir_dev->raw->lirc.carrier_low = val; + break; + case LIRC_SET_SEND_DUTY_CYCLE: + + if (!ir_dev->props->s_tx_duty_cycle) + return -ENOSYS; + + if (val <= 0 || val >= 100) + return -EINVAL; + + ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val); + break; + default: return lirc_dev_fop_ioctl(filep, cmd, arg); } @@ -200,13 +268,25 @@ static int ir_lirc_register(struct input_dev *input_dev) features = LIRC_CAN_REC_MODE2; if (ir_dev->props->tx_ir) { + features |= LIRC_CAN_SEND_PULSE; if (ir_dev->props->s_tx_mask) features |= LIRC_CAN_SET_TRANSMITTER_MASK; if (ir_dev->props->s_tx_carrier) features |= LIRC_CAN_SET_SEND_CARRIER; + + if (ir_dev->props->s_tx_duty_cycle) + features |= LIRC_CAN_SET_REC_DUTY_CYCLE; } + if (ir_dev->props->s_rx_carrier_range) + features |= LIRC_CAN_SET_REC_CARRIER | + LIRC_CAN_SET_REC_CARRIER_RANGE; + + if (ir_dev->props->s_learning_mode) + features |= LIRC_CAN_LEARN_MODE; + + snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", ir_dev->driver_name); drv->minor = -1; diff --git a/include/media/ir-core.h b/include/media/ir-core.h index 53ce966..46cc6c5 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h @@ -44,6 +44,8 @@ enum rc_driver_type { * @timeout: optional time after which device stops sending data * @min_timeout: minimum timeout supported by device * @max_timeout: maximum timeout supported by device + * @rx_resolution : resolution (in ns) of input sampler + * @tx_resolution: resolution (in ns) of output sampler * @priv: driver-specific data, to be used on the callbacks * @change_protocol: allow changing the protocol used on hardware decoders * @open: callback to allow drivers to enable polling/irq when IR input device @@ -52,9 +54,12 @@ enum rc_driver_type { * is opened. * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs) * @s_tx_carrier: set transmit carrier frequency + * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%) + * @s_rx_carrier: inform driver about carrier it is expected to handle * @tx_ir: transmit IR * @s_idle: optional: enable/disable hardware idle mode, upon which, device doesn't interrupt host untill it sees IR data + * @s_learning_mode: enable learning mode */ struct ir_dev_props { enum rc_driver_type driver_type; @@ -65,6 +70,8 @@ struct ir_dev_props { u64 min_timeout; u64 max_timeout; + u32 rx_resolution; + u32 tx_resolution; void *priv; int (*change_protocol)(void *priv, u64 ir_type); @@ -72,8 +79,12 @@ struct ir_dev_props { void (*close)(void *priv); int (*s_tx_mask)(void *priv, u32 mask); int (*s_tx_carrier)(void *priv, u32 carrier); + int (*s_tx_duty_cycle) (void *priv, u32 duty_cycle); + int (*s_rx_carrier_range) (void *priv, u32 min, u32 max); int (*tx_ir)(void *priv, int *txbuf, u32 n); void (*s_idle) (void *priv, int enable); + int (*s_learning_mode) (void *priv, int enable); + }; struct ir_input_dev { diff --git a/include/media/lirc.h b/include/media/lirc.h index 42c467c..09a9753 100644 --- a/include/media/lirc.h +++ b/include/media/lirc.h @@ -76,7 +76,7 @@ #define LIRC_CAN_SET_REC_TIMEOUT 0x10000000 #define LIRC_CAN_SET_REC_FILTER 0x08000000 -#define LIRC_CAN_MEASURE_CARRIER 0x02000000 +#define LIRC_CAN_LEARN_MODE 0x02000000 #define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) #define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) @@ -145,7 +145,7 @@ * if enabled from the next key press on the driver will send * LIRC_MODE2_FREQUENCY packets */ -#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32) +#define LIRC_SET_LEARN_MODE _IOW('i', 0x0000001d, __u32) /* * to set a range use