diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2010-07-31 10:59:23 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-08 22:43:00 -0400 |
commit | e589333f346b58f8da5bb8152e1219c52d375ccc (patch) | |
tree | 4ff05f4f9c5a06c532084ed46b3612ebeec1e21c /drivers/media/IR/ir-lirc-codec.c | |
parent | 4a702ebf61120906696f8366dd2be0653b1643e3 (diff) |
V4L/DVB: IR: extend interfaces to support more device settings
LIRC: add new IOCTL that enables learning mode (wide band receiver)
Still missing features: carrier report & timeout reports.
Will need to pack these into ir_raw_event
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/IR/ir-lirc-codec.c')
-rw-r--r-- | drivers/media/IR/ir-lirc-codec.c | 112 |
1 files changed, 93 insertions, 19 deletions
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 8ca01fd67139..77b5946413c0 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c | |||
@@ -46,7 +46,6 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
46 | IR_dprintk(2, "LIRC data transfer started (%uus %s)\n", | 46 | IR_dprintk(2, "LIRC data transfer started (%uus %s)\n", |
47 | TO_US(ev.duration), TO_STR(ev.pulse)); | 47 | TO_US(ev.duration), TO_STR(ev.pulse)); |
48 | 48 | ||
49 | |||
50 | sample = ev.duration / 1000; | 49 | sample = ev.duration / 1000; |
51 | if (ev.pulse) | 50 | if (ev.pulse) |
52 | sample |= PULSE_BIT; | 51 | sample |= PULSE_BIT; |
@@ -96,13 +95,14 @@ out: | |||
96 | return ret; | 95 | return ret; |
97 | } | 96 | } |
98 | 97 | ||
99 | static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | 98 | static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, |
99 | unsigned long __user arg) | ||
100 | { | 100 | { |
101 | struct lirc_codec *lirc; | 101 | struct lirc_codec *lirc; |
102 | struct ir_input_dev *ir_dev; | 102 | struct ir_input_dev *ir_dev; |
103 | int ret = 0; | 103 | int ret = 0; |
104 | void *drv_data; | 104 | void *drv_data; |
105 | unsigned long val; | 105 | unsigned long val = 0; |
106 | 106 | ||
107 | lirc = lirc_get_pdata(filep); | 107 | lirc = lirc_get_pdata(filep); |
108 | if (!lirc) | 108 | if (!lirc) |
@@ -114,47 +114,106 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long ar | |||
114 | 114 | ||
115 | drv_data = ir_dev->props->priv; | 115 | drv_data = ir_dev->props->priv; |
116 | 116 | ||
117 | switch (cmd) { | 117 | if (_IOC_DIR(cmd) & _IOC_WRITE) { |
118 | case LIRC_SET_TRANSMITTER_MASK: | ||
119 | ret = get_user(val, (unsigned long *)arg); | 118 | ret = get_user(val, (unsigned long *)arg); |
120 | if (ret) | 119 | if (ret) |
121 | return ret; | 120 | return ret; |
121 | } | ||
122 | |||
123 | switch (cmd) { | ||
124 | |||
125 | /* legacy support */ | ||
126 | case LIRC_GET_SEND_MODE: | ||
127 | val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK; | ||
128 | break; | ||
129 | |||
130 | case LIRC_SET_SEND_MODE: | ||
131 | if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) | ||
132 | return -EINVAL; | ||
133 | break; | ||
122 | 134 | ||
123 | if (ir_dev->props && ir_dev->props->s_tx_mask) | 135 | /* TX settings */ |
136 | case LIRC_SET_TRANSMITTER_MASK: | ||
137 | if (ir_dev->props->s_tx_mask) | ||
124 | ret = ir_dev->props->s_tx_mask(drv_data, (u32)val); | 138 | ret = ir_dev->props->s_tx_mask(drv_data, (u32)val); |
125 | else | 139 | else |
126 | return -EINVAL; | 140 | return -EINVAL; |
127 | break; | 141 | break; |
128 | 142 | ||
129 | case LIRC_SET_SEND_CARRIER: | 143 | case LIRC_SET_SEND_CARRIER: |
130 | ret = get_user(val, (unsigned long *)arg); | 144 | if (ir_dev->props->s_tx_carrier) |
131 | if (ret) | ||
132 | return ret; | ||
133 | |||
134 | if (ir_dev->props && ir_dev->props->s_tx_carrier) | ||
135 | ir_dev->props->s_tx_carrier(drv_data, (u32)val); | 145 | ir_dev->props->s_tx_carrier(drv_data, (u32)val); |
136 | else | 146 | else |
137 | return -EINVAL; | 147 | return -EINVAL; |
138 | break; | 148 | break; |
139 | 149 | ||
140 | case LIRC_GET_SEND_MODE: | 150 | case LIRC_SET_SEND_DUTY_CYCLE: |
141 | val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK; | 151 | if (!ir_dev->props->s_tx_duty_cycle) |
142 | ret = put_user(val, (unsigned long *)arg); | 152 | return -ENOSYS; |
153 | |||
154 | if (val <= 0 || val >= 100) | ||
155 | return -EINVAL; | ||
156 | |||
157 | ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val); | ||
143 | break; | 158 | break; |
144 | 159 | ||
145 | case LIRC_SET_SEND_MODE: | 160 | /* RX settings */ |
146 | ret = get_user(val, (unsigned long *)arg); | 161 | case LIRC_SET_REC_CARRIER: |
147 | if (ret) | 162 | if (ir_dev->props->s_rx_carrier_range) |
148 | return ret; | 163 | ret = ir_dev->props->s_rx_carrier_range( |
164 | ir_dev->props->priv, | ||
165 | ir_dev->raw->lirc.carrier_low, val); | ||
166 | else | ||
167 | return -ENOSYS; | ||
149 | 168 | ||
150 | if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) | 169 | if (!ret) |
170 | ir_dev->raw->lirc.carrier_low = 0; | ||
171 | break; | ||
172 | |||
173 | case LIRC_SET_REC_CARRIER_RANGE: | ||
174 | if (val >= 0) | ||
175 | ir_dev->raw->lirc.carrier_low = val; | ||
176 | break; | ||
177 | |||
178 | |||
179 | case LIRC_GET_REC_RESOLUTION: | ||
180 | val = ir_dev->props->rx_resolution; | ||
181 | break; | ||
182 | |||
183 | case LIRC_SET_WIDEBAND_RECEIVER: | ||
184 | if (ir_dev->props->s_learning_mode) | ||
185 | return ir_dev->props->s_learning_mode( | ||
186 | ir_dev->props->priv, !!val); | ||
187 | else | ||
188 | return -ENOSYS; | ||
189 | |||
190 | /* Generic timeout support */ | ||
191 | case LIRC_GET_MIN_TIMEOUT: | ||
192 | if (!ir_dev->props->max_timeout) | ||
193 | return -ENOSYS; | ||
194 | val = ir_dev->props->min_timeout / 1000; | ||
195 | break; | ||
196 | |||
197 | case LIRC_GET_MAX_TIMEOUT: | ||
198 | if (!ir_dev->props->max_timeout) | ||
199 | return -ENOSYS; | ||
200 | val = ir_dev->props->max_timeout / 1000; | ||
201 | break; | ||
202 | |||
203 | case LIRC_SET_REC_TIMEOUT: | ||
204 | if (val < ir_dev->props->min_timeout || | ||
205 | val > ir_dev->props->max_timeout) | ||
151 | return -EINVAL; | 206 | return -EINVAL; |
207 | ir_dev->props->timeout = val * 1000; | ||
152 | break; | 208 | break; |
153 | 209 | ||
154 | default: | 210 | default: |
155 | return lirc_dev_fop_ioctl(filep, cmd, arg); | 211 | return lirc_dev_fop_ioctl(filep, cmd, arg); |
156 | } | 212 | } |
157 | 213 | ||
214 | if (_IOC_DIR(cmd) & _IOC_READ) | ||
215 | ret = put_user(val, (unsigned long *)arg); | ||
216 | |||
158 | return ret; | 217 | return ret; |
159 | } | 218 | } |
160 | 219 | ||
@@ -200,13 +259,28 @@ static int ir_lirc_register(struct input_dev *input_dev) | |||
200 | 259 | ||
201 | features = LIRC_CAN_REC_MODE2; | 260 | features = LIRC_CAN_REC_MODE2; |
202 | if (ir_dev->props->tx_ir) { | 261 | if (ir_dev->props->tx_ir) { |
262 | |||
203 | features |= LIRC_CAN_SEND_PULSE; | 263 | features |= LIRC_CAN_SEND_PULSE; |
204 | if (ir_dev->props->s_tx_mask) | 264 | if (ir_dev->props->s_tx_mask) |
205 | features |= LIRC_CAN_SET_TRANSMITTER_MASK; | 265 | features |= LIRC_CAN_SET_TRANSMITTER_MASK; |
206 | if (ir_dev->props->s_tx_carrier) | 266 | if (ir_dev->props->s_tx_carrier) |
207 | features |= LIRC_CAN_SET_SEND_CARRIER; | 267 | features |= LIRC_CAN_SET_SEND_CARRIER; |
268 | |||
269 | if (ir_dev->props->s_tx_duty_cycle) | ||
270 | features |= LIRC_CAN_SET_REC_DUTY_CYCLE; | ||
208 | } | 271 | } |
209 | 272 | ||
273 | if (ir_dev->props->s_rx_carrier_range) | ||
274 | features |= LIRC_CAN_SET_REC_CARRIER | | ||
275 | LIRC_CAN_SET_REC_CARRIER_RANGE; | ||
276 | |||
277 | if (ir_dev->props->s_learning_mode) | ||
278 | features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; | ||
279 | |||
280 | if (ir_dev->props->max_timeout) | ||
281 | features |= LIRC_CAN_SET_REC_TIMEOUT; | ||
282 | |||
283 | |||
210 | snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", | 284 | snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", |
211 | ir_dev->driver_name); | 285 | ir_dev->driver_name); |
212 | drv->minor = -1; | 286 | drv->minor = -1; |