Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.1-rc4 305 lines 7.0 kB view raw
1/* 2 * Copyright (C) 2008 Nokia Corporation 3 * 4 * Based on lirc_serial.c 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16#include <linux/clk.h> 17#include <linux/module.h> 18#include <linux/platform_device.h> 19#include <linux/wait.h> 20#include <linux/pwm.h> 21#include <linux/of.h> 22#include <linux/hrtimer.h> 23 24#include <media/rc-core.h> 25 26#define WBUF_LEN 256 27 28struct ir_rx51 { 29 struct rc_dev *rcdev; 30 struct pwm_device *pwm; 31 struct hrtimer timer; 32 struct device *dev; 33 wait_queue_head_t wqueue; 34 35 unsigned int freq; /* carrier frequency */ 36 unsigned int duty_cycle; /* carrier duty cycle */ 37 int wbuf[WBUF_LEN]; 38 int wbuf_index; 39 unsigned long device_is_open; 40}; 41 42static inline void ir_rx51_on(struct ir_rx51 *ir_rx51) 43{ 44 pwm_enable(ir_rx51->pwm); 45} 46 47static inline void ir_rx51_off(struct ir_rx51 *ir_rx51) 48{ 49 pwm_disable(ir_rx51->pwm); 50} 51 52static int init_timing_params(struct ir_rx51 *ir_rx51) 53{ 54 struct pwm_device *pwm = ir_rx51->pwm; 55 int duty, period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, ir_rx51->freq); 56 57 duty = DIV_ROUND_CLOSEST(ir_rx51->duty_cycle * period, 100); 58 59 pwm_config(pwm, duty, period); 60 61 return 0; 62} 63 64static enum hrtimer_restart ir_rx51_timer_cb(struct hrtimer *timer) 65{ 66 struct ir_rx51 *ir_rx51 = container_of(timer, struct ir_rx51, timer); 67 ktime_t now; 68 69 if (ir_rx51->wbuf_index < 0) { 70 dev_err_ratelimited(ir_rx51->dev, 71 "BUG wbuf_index has value of %i\n", 72 ir_rx51->wbuf_index); 73 goto end; 74 } 75 76 /* 77 * If we happen to hit an odd latency spike, loop through the 78 * pulses until we catch up. 79 */ 80 do { 81 u64 ns; 82 83 if (ir_rx51->wbuf_index >= WBUF_LEN) 84 goto end; 85 if (ir_rx51->wbuf[ir_rx51->wbuf_index] == -1) 86 goto end; 87 88 if (ir_rx51->wbuf_index % 2) 89 ir_rx51_off(ir_rx51); 90 else 91 ir_rx51_on(ir_rx51); 92 93 ns = US_TO_NS(ir_rx51->wbuf[ir_rx51->wbuf_index]); 94 hrtimer_add_expires_ns(timer, ns); 95 96 ir_rx51->wbuf_index++; 97 98 now = timer->base->get_time(); 99 100 } while (hrtimer_get_expires_tv64(timer) < now); 101 102 return HRTIMER_RESTART; 103end: 104 /* Stop TX here */ 105 ir_rx51_off(ir_rx51); 106 ir_rx51->wbuf_index = -1; 107 108 wake_up_interruptible(&ir_rx51->wqueue); 109 110 return HRTIMER_NORESTART; 111} 112 113static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer, 114 unsigned int count) 115{ 116 struct ir_rx51 *ir_rx51 = dev->priv; 117 118 if (count > WBUF_LEN) 119 return -EINVAL; 120 121 memcpy(ir_rx51->wbuf, buffer, count * sizeof(unsigned int)); 122 123 /* Wait any pending transfers to finish */ 124 wait_event_interruptible(ir_rx51->wqueue, ir_rx51->wbuf_index < 0); 125 126 init_timing_params(ir_rx51); 127 if (count < WBUF_LEN) 128 ir_rx51->wbuf[count] = -1; /* Insert termination mark */ 129 130 /* 131 * REVISIT: Adjust latency requirements so the device doesn't go in too 132 * deep sleep states with pm_qos_add_request(). 133 */ 134 135 ir_rx51_on(ir_rx51); 136 ir_rx51->wbuf_index = 1; 137 hrtimer_start(&ir_rx51->timer, 138 ns_to_ktime(US_TO_NS(ir_rx51->wbuf[0])), 139 HRTIMER_MODE_REL); 140 /* 141 * Don't return back to the userspace until the transfer has 142 * finished 143 */ 144 wait_event_interruptible(ir_rx51->wqueue, ir_rx51->wbuf_index < 0); 145 146 /* REVISIT: Remove pm_qos constraint, we can sleep again */ 147 148 return count; 149} 150 151static int ir_rx51_open(struct rc_dev *dev) 152{ 153 struct ir_rx51 *ir_rx51 = dev->priv; 154 155 if (test_and_set_bit(1, &ir_rx51->device_is_open)) 156 return -EBUSY; 157 158 ir_rx51->pwm = pwm_get(ir_rx51->dev, NULL); 159 if (IS_ERR(ir_rx51->pwm)) { 160 int res = PTR_ERR(ir_rx51->pwm); 161 162 dev_err(ir_rx51->dev, "pwm_get failed: %d\n", res); 163 return res; 164 } 165 166 return 0; 167} 168 169static void ir_rx51_release(struct rc_dev *dev) 170{ 171 struct ir_rx51 *ir_rx51 = dev->priv; 172 173 hrtimer_cancel(&ir_rx51->timer); 174 ir_rx51_off(ir_rx51); 175 pwm_put(ir_rx51->pwm); 176 177 clear_bit(1, &ir_rx51->device_is_open); 178} 179 180static struct ir_rx51 ir_rx51 = { 181 .duty_cycle = 50, 182 .wbuf_index = -1, 183}; 184 185static int ir_rx51_set_duty_cycle(struct rc_dev *dev, u32 duty) 186{ 187 struct ir_rx51 *ir_rx51 = dev->priv; 188 189 ir_rx51->duty_cycle = duty; 190 191 return 0; 192} 193 194static int ir_rx51_set_tx_carrier(struct rc_dev *dev, u32 carrier) 195{ 196 struct ir_rx51 *ir_rx51 = dev->priv; 197 198 if (carrier > 500000 || carrier < 20000) 199 return -EINVAL; 200 201 ir_rx51->freq = carrier; 202 203 return 0; 204} 205 206#ifdef CONFIG_PM 207 208static int ir_rx51_suspend(struct platform_device *dev, pm_message_t state) 209{ 210 /* 211 * In case the device is still open, do not suspend. Normally 212 * this should not be a problem as lircd only keeps the device 213 * open only for short periods of time. We also don't want to 214 * get involved with race conditions that might happen if we 215 * were in a middle of a transmit. Thus, we defer any suspend 216 * actions until transmit has completed. 217 */ 218 if (test_and_set_bit(1, &ir_rx51.device_is_open)) 219 return -EAGAIN; 220 221 clear_bit(1, &ir_rx51.device_is_open); 222 223 return 0; 224} 225 226static int ir_rx51_resume(struct platform_device *dev) 227{ 228 return 0; 229} 230 231#else 232 233#define ir_rx51_suspend NULL 234#define ir_rx51_resume NULL 235 236#endif /* CONFIG_PM */ 237 238static int ir_rx51_probe(struct platform_device *dev) 239{ 240 struct pwm_device *pwm; 241 struct rc_dev *rcdev; 242 243 pwm = pwm_get(&dev->dev, NULL); 244 if (IS_ERR(pwm)) { 245 int err = PTR_ERR(pwm); 246 247 if (err != -EPROBE_DEFER) 248 dev_err(&dev->dev, "pwm_get failed: %d\n", err); 249 return err; 250 } 251 252 /* Use default, in case userspace does not set the carrier */ 253 ir_rx51.freq = DIV_ROUND_CLOSEST(pwm_get_period(pwm), NSEC_PER_SEC); 254 pwm_put(pwm); 255 256 hrtimer_init(&ir_rx51.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 257 ir_rx51.timer.function = ir_rx51_timer_cb; 258 259 ir_rx51.dev = &dev->dev; 260 261 rcdev = devm_rc_allocate_device(&dev->dev, RC_DRIVER_IR_RAW_TX); 262 if (!rcdev) 263 return -ENOMEM; 264 265 rcdev->priv = &ir_rx51; 266 rcdev->open = ir_rx51_open; 267 rcdev->close = ir_rx51_release; 268 rcdev->tx_ir = ir_rx51_tx; 269 rcdev->s_tx_duty_cycle = ir_rx51_set_duty_cycle; 270 rcdev->s_tx_carrier = ir_rx51_set_tx_carrier; 271 rcdev->driver_name = KBUILD_MODNAME; 272 273 ir_rx51.rcdev = rcdev; 274 275 return devm_rc_register_device(&dev->dev, ir_rx51.rcdev); 276} 277 278static int ir_rx51_remove(struct platform_device *dev) 279{ 280 return 0; 281} 282 283static const struct of_device_id ir_rx51_match[] = { 284 { 285 .compatible = "nokia,n900-ir", 286 }, 287 {}, 288}; 289MODULE_DEVICE_TABLE(of, ir_rx51_match); 290 291static struct platform_driver ir_rx51_platform_driver = { 292 .probe = ir_rx51_probe, 293 .remove = ir_rx51_remove, 294 .suspend = ir_rx51_suspend, 295 .resume = ir_rx51_resume, 296 .driver = { 297 .name = KBUILD_MODNAME, 298 .of_match_table = of_match_ptr(ir_rx51_match), 299 }, 300}; 301module_platform_driver(ir_rx51_platform_driver); 302 303MODULE_DESCRIPTION("IR TX driver for Nokia RX51"); 304MODULE_AUTHOR("Nokia Corporation"); 305MODULE_LICENSE("GPL");