aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-lirc-codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/IR/ir-lirc-codec.c')
-rw-r--r--drivers/media/IR/ir-lirc-codec.c124
1 files changed, 100 insertions, 24 deletions
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
index 3ba482d96c4b..77b5946413c0 100644
--- a/drivers/media/IR/ir-lirc-codec.c
+++ b/drivers/media/IR/ir-lirc-codec.c
@@ -32,6 +32,7 @@
32static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) 32static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
33{ 33{
34 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 34 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
35 int sample;
35 36
36 if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) 37 if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
37 return 0; 38 return 0;
@@ -39,18 +40,20 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
39 if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) 40 if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
40 return -EINVAL; 41 return -EINVAL;
41 42
43 if (IS_RESET(ev))
44 return 0;
45
42 IR_dprintk(2, "LIRC data transfer started (%uus %s)\n", 46 IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
43 TO_US(ev.duration), TO_STR(ev.pulse)); 47 TO_US(ev.duration), TO_STR(ev.pulse));
44 48
45 ir_dev->raw->lirc.lircdata += ev.duration / 1000; 49 sample = ev.duration / 1000;
46 if (ev.pulse) 50 if (ev.pulse)
47 ir_dev->raw->lirc.lircdata |= PULSE_BIT; 51 sample |= PULSE_BIT;
48 52
49 lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, 53 lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
50 (unsigned char *) &ir_dev->raw->lirc.lircdata); 54 (unsigned char *) &sample);
51 wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); 55 wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
52 56
53 ir_dev->raw->lirc.lircdata = 0;
54 57
55 return 0; 58 return 0;
56} 59}
@@ -92,13 +95,14 @@ out:
92 return ret; 95 return ret;
93} 96}
94 97
95static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) 98static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
99 unsigned long __user arg)
96{ 100{
97 struct lirc_codec *lirc; 101 struct lirc_codec *lirc;
98 struct ir_input_dev *ir_dev; 102 struct ir_input_dev *ir_dev;
99 int ret = 0; 103 int ret = 0;
100 void *drv_data; 104 void *drv_data;
101 unsigned long val; 105 unsigned long val = 0;
102 106
103 lirc = lirc_get_pdata(filep); 107 lirc = lirc_get_pdata(filep);
104 if (!lirc) 108 if (!lirc)
@@ -110,47 +114,106 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long ar
110 114
111 drv_data = ir_dev->props->priv; 115 drv_data = ir_dev->props->priv;
112 116
113 switch (cmd) { 117 if (_IOC_DIR(cmd) & _IOC_WRITE) {
114 case LIRC_SET_TRANSMITTER_MASK:
115 ret = get_user(val, (unsigned long *)arg); 118 ret = get_user(val, (unsigned long *)arg);
116 if (ret) 119 if (ret)
117 return ret; 120 return ret;
121 }
122
123 switch (cmd) {
118 124
119 if (ir_dev->props && ir_dev->props->s_tx_mask) 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;
134
135 /* TX settings */
136 case LIRC_SET_TRANSMITTER_MASK:
137 if (ir_dev->props->s_tx_mask)
120 ret = ir_dev->props->s_tx_mask(drv_data, (u32)val); 138 ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
121 else 139 else
122 return -EINVAL; 140 return -EINVAL;
123 break; 141 break;
124 142
125 case LIRC_SET_SEND_CARRIER: 143 case LIRC_SET_SEND_CARRIER:
126 ret = get_user(val, (unsigned long *)arg); 144 if (ir_dev->props->s_tx_carrier)
127 if (ret)
128 return ret;
129
130 if (ir_dev->props && ir_dev->props->s_tx_carrier)
131 ir_dev->props->s_tx_carrier(drv_data, (u32)val); 145 ir_dev->props->s_tx_carrier(drv_data, (u32)val);
132 else 146 else
133 return -EINVAL; 147 return -EINVAL;
134 break; 148 break;
135 149
136 case LIRC_GET_SEND_MODE: 150 case LIRC_SET_SEND_DUTY_CYCLE:
137 val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK; 151 if (!ir_dev->props->s_tx_duty_cycle)
138 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);
139 break; 158 break;
140 159
141 case LIRC_SET_SEND_MODE: 160 /* RX settings */
142 ret = get_user(val, (unsigned long *)arg); 161 case LIRC_SET_REC_CARRIER:
143 if (ret) 162 if (ir_dev->props->s_rx_carrier_range)
144 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;
145 168
146 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)
147 return -EINVAL; 206 return -EINVAL;
207 ir_dev->props->timeout = val * 1000;
148 break; 208 break;
149 209
150 default: 210 default:
151 return lirc_dev_fop_ioctl(filep, cmd, arg); 211 return lirc_dev_fop_ioctl(filep, cmd, arg);
152 } 212 }
153 213
214 if (_IOC_DIR(cmd) & _IOC_READ)
215 ret = put_user(val, (unsigned long *)arg);
216
154 return ret; 217 return ret;
155} 218}
156 219
@@ -196,13 +259,28 @@ static int ir_lirc_register(struct input_dev *input_dev)
196 259
197 features = LIRC_CAN_REC_MODE2; 260 features = LIRC_CAN_REC_MODE2;
198 if (ir_dev->props->tx_ir) { 261 if (ir_dev->props->tx_ir) {
262
199 features |= LIRC_CAN_SEND_PULSE; 263 features |= LIRC_CAN_SEND_PULSE;
200 if (ir_dev->props->s_tx_mask) 264 if (ir_dev->props->s_tx_mask)
201 features |= LIRC_CAN_SET_TRANSMITTER_MASK; 265 features |= LIRC_CAN_SET_TRANSMITTER_MASK;
202 if (ir_dev->props->s_tx_carrier) 266 if (ir_dev->props->s_tx_carrier)
203 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;
204 } 271 }
205 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
206 snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", 284 snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
207 ir_dev->driver_name); 285 ir_dev->driver_name);
208 drv->minor = -1; 286 drv->minor = -1;
@@ -224,8 +302,6 @@ static int ir_lirc_register(struct input_dev *input_dev)
224 302
225 ir_dev->raw->lirc.drv = drv; 303 ir_dev->raw->lirc.drv = drv;
226 ir_dev->raw->lirc.ir_dev = ir_dev; 304 ir_dev->raw->lirc.ir_dev = ir_dev;
227 ir_dev->raw->lirc.lircdata = PULSE_MASK;
228
229 return 0; 305 return 0;
230 306
231lirc_register_failed: 307lirc_register_failed: