內核版本:2.6.36
源碼路徑:drivers/input/touchscreen/s3c2410_ts.c
在Linux-2.6.36中,S3C2410對應的觸摸屏驅動程序是drivers/input/touchscreen/s3c2410_ts.c,本文對這個文件進行分析,詳細介紹相關知識點。S3C2410的觸摸屏驅動和ADC驅動緊密聯系在一起,在讀本文之前,請大家先看我的這篇《S3C2410驅動分析之ADC通用驅動》http://www.linuxidc.com/Linux/2012-04/58701.htm。
首先我們看模塊初始化函數:
該驅動程序是以platform driver的方式注冊的,這裡注冊的platform_driver是s3c_ts_driver,其定義如下:
- 436static int __init s3c2410ts_init(void)
- 437{
- 438 return platform_driver_register(&s3c_ts_driver);
- 439}
這裡需要關注的是platform_driver結構的id_table和probe兩個成員。s3cts_driver_ids定義如下:
- 423static struct platform_driver s3c_ts_driver = {
- 424 .driver = {
- 425 .name = "samsung-ts",
- 426 .owner = THIS_MODULE,
- 427#ifdef CONFIG_PM
- 428 .pm = &s3c_ts_pmops,
- 429#endif
- 430 },
- 431 .id_table = s3cts_driver_ids,
- 432 .probe = s3c2410ts_probe,
- 433 .remove = __devexit_p(s3c2410ts_remove),
- 434};
421MODULE_DEVICE_TABLE(platform, s3cts_driver_ids);
- 415static struct platform_device_id s3cts_driver_ids[] = {
- 416 { "s3c2410-ts", 0 },
- 417 { "s3c2440-ts", 0 },
- 418 { "s3c64xx-ts", FEAT_PEN_IRQ },
- 419 { }
- 420};
probe成員函數s3c2410ts_probe當模塊被加載時就會執行,其代碼如下:
243行,定義s3c2410_ts_mach_info結構體變量info,該結構體定義在arch/arm/plat-samsung/include/plat/ts.h文件中:
- 234/**
- 235 * s3c2410ts_probe - device core probe entry point
- 236 * @pdev: The device we are being bound to.
- 237 *
- 238 * Initialise, find and allocate any resources we need to run and then
- 239 * register with the ADC and input systems.
- 240 */
- 241static int __devinit s3c2410ts_probe(struct platform_device *pdev)
- 242{
- 243 struct s3c2410_ts_mach_info *info;
- 244 struct device *dev = &pdev->dev;
- 245 struct input_dev *input_dev;
- 246 struct resource *res;
- 247 int ret = -EINVAL;
- 248
- 249 /* Initialise input stuff */
- 250 memset(&ts, 0, sizeof(struct s3c2410ts));
- 251
- 252 ts.dev = dev;
- 253
- 254 info = pdev->dev.platform_data;
- 255 if (!info) {
- 256 dev_err(dev, "no platform data, cannot attach\n");
- 257 return -EINVAL;
- 258 }
- 259
- 260 dev_dbg(dev, "initialising touchscreen\n");
- 261
- 262 ts.clock = clk_get(dev, "adc");
- 263 if (IS_ERR(ts.clock)) {
- 264 dev_err(dev, "cannot get adc clock source\n");
- 265 return -ENOENT;
- 266 }
- 267
- 268 clk_enable(ts.clock);
- 269 dev_dbg(dev, "got and enabled clocks\n");
- 270
- 271 ts.irq_tc = ret = platform_get_irq(pdev, 0);
- 272 if (ret < 0) {
- 273 dev_err(dev, "no resource for interrupt\n");
- 274 goto err_clk;
- 275 }
- 276
- 277 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- 278 if (!res) {
- 279 dev_err(dev, "no resource for registers\n");
- 280 ret = -ENOENT;
- 281 goto err_clk;
- 282 }
- 283
- 284 ts.io = ioremap(res->start, resource_size(res));
- 285 if (ts.io == NULL) {
- 286 dev_err(dev, "cannot map registers\n");
- 287 ret = -ENOMEM;
- 288 goto err_clk;
- 289 }
- 290
- 291 /* inititalise the gpio */
- 292 if (info->cfg_gpio)
- 293 info->cfg_gpio(to_platform_device(ts.dev));
- 294
- 295 ts.client = s3c_adc_register(pdev, s3c24xx_ts_select,
- 296 s3c24xx_ts_conversion, 1);
- 297 if (IS_ERR(ts.client)) {
- 298 dev_err(dev, "failed to register adc client\n");
- 299 ret = PTR_ERR(ts.client);
- 300 goto err_iomap;
- 301 }
- 302
- 303 /* Initialise registers */
- 304 if ((info->delay & 0xffff) > 0)
- 305 writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY);
- 306
- 307 writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
- 308
- 309 input_dev = input_allocate_device();
- 310 if (!input_dev) {
- 311 dev_err(dev, "Unable to allocate the input device !!\n");
- 312 ret = -ENOMEM;
- 313 goto err_iomap;
- 314 }
- 315
- 316 ts.input = input_dev;
- 317 ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- 318 ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
- 319 input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0);
- 320 input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0);
- 321
- 322 ts.input->name = "S3C24XX TouchScreen";
- 323 ts.input->id.bustype = BUS_HOST;
- 324 ts.input->id.vendor = 0xDEAD;
- 325 ts.input->id.product = 0xBEEF;
- 326 ts.input->id.version = 0x0102;
- 327
- 328 ts.shift = info->oversampling_shift;
- 329 ts.features = platform_get_device_id(pdev)->driver_data;
- 330
- 331 ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED,
- 332 "s3c2410_ts_pen", ts.input);
- 333 if (ret) {
- 334 dev_err(dev, "cannot get TC interrupt\n");
- 335 goto err_inputdev;
- 336 }
- 337
- 338 dev_info(dev, "driver attached, registering input device\n");
- 339
- 340 /* All went ok, so register to the input system */
- 341 ret = input_register_device(ts.input);
- 342 if (ret < 0) {
- 343 dev_err(dev, "failed to register input device\n");
- 344 ret = -EIO;
- 345 goto err_tcirq;
- 346 }
- 347
- 348 return 0;
- 349
- 350 err_tcirq:
- 351 free_irq(ts.irq_tc, ts.input);
- 352 err_inputdev:
- 353 input_unregister_device(ts.input);
- 354 err_iomap:
- 355 iounmap(ts.io);
- 356 err_clk:
- 357 del_timer_sync(&touch_timer);
- 358 clk_put(ts.clock);
- 359 return ret;
- 360}
delay保存ADC的延遲時間。
- 13struct s3c2410_ts_mach_info {
- 14 int delay;
- 15 int presc;
- 16 int oversampling_shift;
- 17 void (*cfg_gpio)(struct platform_device *dev);
- 18};
presc保存ADC的預分頻系數。
oversampling_shift保存采樣次數log2值。
cfg_gpio函數用於設置gpio。
250行,將ts清0,ts是s3c2410ts結構體類型變量,其定義如下:
s3c2410ts結構體的各個成員的含義在注冊中已經說的很清楚,這裡不再解釋。
- 62/**
- 63 * struct s3c2410ts - driver touchscreen state.
- 64 * @client: The ADC client we registered with the core driver.
- 65 * @dev: The device we are bound to.
- 66 * @input: The input device we registered with the input subsystem.
- 67 * @clock: The clock for the adc.
- 68 * @io: Pointer to the IO base.
- 69 * @xp: The accumulated X position data.
- 70 * @yp: The accumulated Y position data.
- 71 * @irq_tc: The interrupt number for pen up/down interrupt
- 72 * @count: The number of samples collected.
- 73 * @shift: The log2 of the maximum count to read in one go.
- 74 * @features: The features supported by the TSADC MOdule.
- 75 */
- 76struct s3c2410ts {
- 77 struct s3c_adc_client *client;
- 78 struct device *dev;
- 79 struct input_dev *input;
- 80 struct clk *clock;
- 81 void __iomem *io;
- 82 unsigned long xp;
- 83 unsigned long yp;
- 84 int irq_tc;
- 85 int count;
- 86 int shift;
- 87 int features;
- 88};
- 89
- 90static struct s3c2410ts ts;