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.c135
1 files changed, 95 insertions, 40 deletions
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
index 1983cd3f3994..9fc0db9d344d 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 struct lirc_codec *lirc = &ir_dev->raw->lirc;
35 int sample; 36 int sample;
36 37
37 if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) 38 if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
@@ -40,21 +41,57 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
40 if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) 41 if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
41 return -EINVAL; 42 return -EINVAL;
42 43
43 if (IS_RESET(ev)) 44 /* Packet start */
45 if (ev.reset)
44 return 0; 46 return 0;
45 47
46 IR_dprintk(2, "LIRC data transfer started (%uus %s)\n", 48 /* Carrier reports */
47 TO_US(ev.duration), TO_STR(ev.pulse)); 49 if (ev.carrier_report) {
50 sample = LIRC_FREQUENCY(ev.carrier);
51
52 /* Packet end */
53 } else if (ev.timeout) {
54
55 if (lirc->gap)
56 return 0;
57
58 lirc->gap_start = ktime_get();
59 lirc->gap = true;
60 lirc->gap_duration = ev.duration;
61
62 if (!lirc->send_timeout_reports)
63 return 0;
64
65 sample = LIRC_TIMEOUT(ev.duration / 1000);
48 66
49 sample = ev.duration / 1000; 67 /* Normal sample */
50 if (ev.pulse) 68 } else {
51 sample |= PULSE_BIT; 69
70 if (lirc->gap) {
71 int gap_sample;
72
73 lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
74 lirc->gap_start));
75
76 /* Convert to ms and cap by LIRC_VALUE_MASK */
77 do_div(lirc->gap_duration, 1000);
78 lirc->gap_duration = min(lirc->gap_duration,
79 (u64)LIRC_VALUE_MASK);
80
81 gap_sample = LIRC_SPACE(lirc->gap_duration);
82 lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
83 (unsigned char *) &gap_sample);
84 lirc->gap = false;
85 }
86
87 sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
88 LIRC_SPACE(ev.duration / 1000);
89 }
52 90
53 lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, 91 lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
54 (unsigned char *) &sample); 92 (unsigned char *) &sample);
55 wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); 93 wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
56 94
57
58 return 0; 95 return 0;
59} 96}
60 97
@@ -102,7 +139,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
102 struct ir_input_dev *ir_dev; 139 struct ir_input_dev *ir_dev;
103 int ret = 0; 140 int ret = 0;
104 void *drv_data; 141 void *drv_data;
105 unsigned long val = 0; 142 __u32 val = 0, tmp;
106 143
107 lirc = lirc_get_pdata(filep); 144 lirc = lirc_get_pdata(filep);
108 if (!lirc) 145 if (!lirc)
@@ -115,7 +152,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
115 drv_data = ir_dev->props->priv; 152 drv_data = ir_dev->props->priv;
116 153
117 if (_IOC_DIR(cmd) & _IOC_WRITE) { 154 if (_IOC_DIR(cmd) & _IOC_WRITE) {
118 ret = get_user(val, (unsigned long *)arg); 155 ret = get_user(val, (__u32 *)arg);
119 if (ret) 156 if (ret)
120 return ret; 157 return ret;
121 } 158 }
@@ -130,22 +167,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
130 case LIRC_SET_SEND_MODE: 167 case LIRC_SET_SEND_MODE:
131 if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) 168 if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
132 return -EINVAL; 169 return -EINVAL;
133 break; 170 return 0;
134 171
135 /* TX settings */ 172 /* TX settings */
136 case LIRC_SET_TRANSMITTER_MASK: 173 case LIRC_SET_TRANSMITTER_MASK:
137 if (ir_dev->props->s_tx_mask) 174 if (!ir_dev->props->s_tx_mask)
138 ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
139 else
140 return -EINVAL; 175 return -EINVAL;
141 break; 176
177 return ir_dev->props->s_tx_mask(drv_data, val);
142 178
143 case LIRC_SET_SEND_CARRIER: 179 case LIRC_SET_SEND_CARRIER:
144 if (ir_dev->props->s_tx_carrier) 180 if (!ir_dev->props->s_tx_carrier)
145 ir_dev->props->s_tx_carrier(drv_data, (u32)val);
146 else
147 return -EINVAL; 181 return -EINVAL;
148 break; 182
183 return ir_dev->props->s_tx_carrier(drv_data, val);
149 184
150 case LIRC_SET_SEND_DUTY_CYCLE: 185 case LIRC_SET_SEND_DUTY_CYCLE:
151 if (!ir_dev->props->s_tx_duty_cycle) 186 if (!ir_dev->props->s_tx_duty_cycle)
@@ -154,39 +189,42 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
154 if (val <= 0 || val >= 100) 189 if (val <= 0 || val >= 100)
155 return -EINVAL; 190 return -EINVAL;
156 191
157 ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val); 192 return ir_dev->props->s_tx_duty_cycle(drv_data, val);
158 break;
159 193
160 /* RX settings */ 194 /* RX settings */
161 case LIRC_SET_REC_CARRIER: 195 case LIRC_SET_REC_CARRIER:
162 if (ir_dev->props->s_rx_carrier_range) 196 if (!ir_dev->props->s_rx_carrier_range)
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; 197 return -ENOSYS;
168 198
169 if (!ret) 199 if (val <= 0)
170 ir_dev->raw->lirc.carrier_low = 0; 200 return -EINVAL;
171 break; 201
202 return ir_dev->props->s_rx_carrier_range(drv_data,
203 ir_dev->raw->lirc.carrier_low, val);
172 204
173 case LIRC_SET_REC_CARRIER_RANGE: 205 case LIRC_SET_REC_CARRIER_RANGE:
174 if (val >= 0) 206 if (val <= 0)
175 ir_dev->raw->lirc.carrier_low = val; 207 return -EINVAL;
176 break;
177 208
209 ir_dev->raw->lirc.carrier_low = val;
210 return 0;
178 211
179 case LIRC_GET_REC_RESOLUTION: 212 case LIRC_GET_REC_RESOLUTION:
180 val = ir_dev->props->rx_resolution; 213 val = ir_dev->props->rx_resolution;
181 break; 214 break;
182 215
183 case LIRC_SET_WIDEBAND_RECEIVER: 216 case LIRC_SET_WIDEBAND_RECEIVER:
184 if (ir_dev->props->s_learning_mode) 217 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; 218 return -ENOSYS;
189 219
220 return ir_dev->props->s_learning_mode(drv_data, !!val);
221
222 case LIRC_SET_MEASURE_CARRIER_MODE:
223 if (!ir_dev->props->s_carrier_report)
224 return -ENOSYS;
225
226 return ir_dev->props->s_carrier_report(drv_data, !!val);
227
190 /* Generic timeout support */ 228 /* Generic timeout support */
191 case LIRC_GET_MIN_TIMEOUT: 229 case LIRC_GET_MIN_TIMEOUT:
192 if (!ir_dev->props->max_timeout) 230 if (!ir_dev->props->max_timeout)
@@ -201,10 +239,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
201 break; 239 break;
202 240
203 case LIRC_SET_REC_TIMEOUT: 241 case LIRC_SET_REC_TIMEOUT:
204 if (val < ir_dev->props->min_timeout || 242 if (!ir_dev->props->max_timeout)
205 val > ir_dev->props->max_timeout) 243 return -ENOSYS;
206 return -EINVAL; 244
207 ir_dev->props->timeout = val * 1000; 245 tmp = val * 1000;
246
247 if (tmp < ir_dev->props->min_timeout ||
248 tmp > ir_dev->props->max_timeout)
249 return -EINVAL;
250
251 ir_dev->props->timeout = tmp;
252 break;
253
254 case LIRC_SET_REC_TIMEOUT_REPORTS:
255 lirc->send_timeout_reports = !!val;
208 break; 256 break;
209 257
210 default: 258 default:
@@ -212,7 +260,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
212 } 260 }
213 261
214 if (_IOC_DIR(cmd) & _IOC_READ) 262 if (_IOC_DIR(cmd) & _IOC_READ)
215 ret = put_user(val, (unsigned long *)arg); 263 ret = put_user(val, (__u32 *)arg);
216 264
217 return ret; 265 return ret;
218} 266}
@@ -231,6 +279,9 @@ static struct file_operations lirc_fops = {
231 .owner = THIS_MODULE, 279 .owner = THIS_MODULE,
232 .write = ir_lirc_transmit_ir, 280 .write = ir_lirc_transmit_ir,
233 .unlocked_ioctl = ir_lirc_ioctl, 281 .unlocked_ioctl = ir_lirc_ioctl,
282#ifdef CONFIG_COMPAT
283 .compat_ioctl = ir_lirc_ioctl,
284#endif
234 .read = lirc_dev_fop_read, 285 .read = lirc_dev_fop_read,
235 .poll = lirc_dev_fop_poll, 286 .poll = lirc_dev_fop_poll,
236 .open = lirc_dev_fop_open, 287 .open = lirc_dev_fop_open,
@@ -278,6 +329,10 @@ static int ir_lirc_register(struct input_dev *input_dev)
278 if (ir_dev->props->s_learning_mode) 329 if (ir_dev->props->s_learning_mode)
279 features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; 330 features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
280 331
332 if (ir_dev->props->s_carrier_report)
333 features |= LIRC_CAN_MEASURE_CARRIER;
334
335
281 if (ir_dev->props->max_timeout) 336 if (ir_dev->props->max_timeout)
282 features |= LIRC_CAN_SET_REC_TIMEOUT; 337 features |= LIRC_CAN_SET_REC_TIMEOUT;
283 338