/*! \pre register_channel (uint8_t channel, uint8_t prescale,void (*conversion_function)(uint16_t)); \param channel choses the channel of the ADC which should be converted \param mode choses between SingleShot and FreeRunning AD- Conversion \return is the value of the ADMUX */ uint8_t start_conversion(uint8_t channel, uint8_t mode){ //used the adc.c methodes to configure the ADC set_adc_mode(channel); set_adc_prescaler(prescalearry[channel]); //gets the asigned function pointer of the channel for the interrupt functiontemp=pointerarray[channel]; set_adc_interruptenable(); //selects between the to possible modes if(mode==FREE){ set_freerunning();} else { ADCSRA |= (1<<ADEN); if( (ADCSRA & (1<<ADSC)) == 0){ ADCSRA |= (1<<ADSC); } } return ADMUX; }
/* 初始化函数 */ static int __init ts_init(void) { int err = -ENOMEM; struct ts_data *ts; /* 给 ts 数据分配空间 */ ts = kzalloc(sizeof(struct ts_data), GFP_KERNEL); if (!ts) goto kzalloc_ts_fail; /* 给输入设备分配空间 */ dev = input_allocate_device(); if (!dev) goto input_allocate_fail; /* 获取并打开时钟源 */ ts->clk = clk_get(NULL, "adc"); if (!ts->clk) { pr_err("clk_get(adc) ERR!\n"); err = -ENOENT; goto clk_get_fail; } clk_enable(ts->clk); /* 设置 GPIO 管脚的功能 */ s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON); s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON); s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON); s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON); /* 申请 IO 内存 */ if (!request_mem_region(S3C24XX_PA_ADC, S3C24XX_SZ_ADC, DEVNAME)) { pr_err("ts_init: request_mem_region() ERR!\n"); err = -EBUSY; goto request_mem_fail; } /* 映射 IO 内存 */ ts->iobase = ioremap(S3C24XX_PA_ADC, S3C24XX_SZ_ADC); if (!ts->iobase) { pr_err("ts_init: ioremap() ERR!\n"); goto ioremap_fail; } /* 初始化定时器 */ setup_timer(&ts->timer, ts_timer, (unsigned long)dev); /* 初始化数据 */ clear_data(ts); /* 初始化输入设备 */ dev->name = DEVNAME; /* 名称 */ /* 设置输入设备的私有数据 */ input_set_drvdata(dev, ts); /* 设置输入设备的功能 */ input_set_capability(dev, EV_KEY, BTN_TOUCH); input_set_capability(dev, EV_ABS, ABS_X); input_set_capability(dev, EV_ABS, ABS_Y); /* 设置绝对坐标事件参数 */ input_set_abs_params(dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0); input_set_abs_params(dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0); /* 申请中断 */ if (request_irq(IRQ_ADC, adc_handler, IRQF_DISABLED, DEVNAME, dev)) { pr_err("request_irq(IRQ_ADC) ERR!\n"); err = -EBUSY; goto request_irq_adc_fail; } if (request_irq(IRQ_TC, tc_handler, IRQF_DISABLED, DEVNAME, dev)) { pr_err("request_irq(IRQ_TC) ERR!\n"); err = -EBUSY; goto request_irq_tc_fail; } /* 注册输入设备 */ if (input_register_device(dev)) { pr_err("input_register_device ERR!\n"); goto input_register_fail; } /* 设置 ADC 时钟的预分频值,以下设置必须放在 IO 内存映射之后 */ set_adc_prescaler(ts, ADC_PRESCALER); /* 设置转换延时 */ set_adc_delay(ts, ADC_DELAY); /* 设置 ADC 为等待中断模式 */ set_adc_wait4int(ts); /* 设置 ADC 为非备用模式 */ set_adc_standby(ts, 0); /* 关闭 ADC 的读触发功能 */ set_adc_read_start(ts, 0); return 0; input_register_fail: free_irq(IRQ_TC, dev); request_irq_tc_fail: free_irq(IRQ_ADC, dev); request_irq_adc_fail: iounmap(ts->iobase); ioremap_fail: release_mem_region(S3C24XX_PA_ADC, S3C24XX_SZ_ADC); request_mem_fail: clk_disable(ts->clk); clk_put(ts->clk); clk_get_fail: input_free_device(dev); input_allocate_fail: kfree(ts); kzalloc_ts_fail: return err; }