|
这个我试试
我将对ADC寄存器的配置写到我的驱动文件中,得到 的结果是:TSADCCON0中的ADC转换完成标志一直都是0,也就是始终没有转换完成。其代码如下:
probe函数:
- static int __init test_adc_bat_probe(struct platform_device *pdev)
- {
- int ret = -1;
-
- /* for adc: AIN0 - AIN9 */
- adc_base_addr = ioremap(S5PV210_PA_ADC + TSADCCON0, 0x1024);
- if(adc_base_addr == NULL)
- {
- ret = -ENOENT;
- printk(KERN_ERR "%s: ioremap for adc failed", __func__);
- return ret;
- }
-
- adc_normal_mode();
- /* set clk */
- adc_clk = clk_get(&pdev->dev, "adc");
- if(IS_ERR(adc_clk))
- {
- printk(KERN_ERR "%s: get adc clk failed!\n", __func__);
- return -1;
- }
- /* anable clk */
- clk_enable(adc_clk);
- /* for irq_adc */
- ret = request_irq(adc_irq_res.start, adc_irq_func, 0, "adc_irq_func", (void *)pbat);
- if(ret != 0)
- {
- printk(KERN_ERR "%s: request irq for adc failed!\n", __func__);
- return -1;
- }
- ret = test_power_init(pdev);
- if(ret != 0)
- {
- printk(KERN_ERR "%s: test_power_init failed!\n", __func__);
- return -1;
- }
- device_init_wakeup(&pdev->dev, 1);
- return 0;
- }
复制代码
probe中的adc_normal_mode函数如下:
- static void adc_normal_mode(void)
- {
- /* prescaler value is 19 */
- writel(S3C_ADCCON_PRSCEN | ((19 & 0xff) << 6), adc_base_addr + TSADCCON0);
- /* delay time 10ms */
- writel(10, adc_base_addr + TSADCCON0 + TSDLY);
- /* adc bits: 12 */
- writel(readl(adc_base_addr + TSADCCON0) | S3C_ADCCON_RESSEL_12BIT, adc_base_addr + TSADCCON0);
- /* when read data register, start to convert */
- writel((readl(adc_base_addr + TSADCCON0) | S3C_ADCCON_READ_START), adc_base_addr + TSADCCON0);
- /* switches and pull-up resistor should be turn off */
- writel(0x58, adc_base_addr + TSADCCON0 + TSCON);
- writel(0x58, adc_base_addr + TSADCCON1 + TSCON);
- }
复制代码
probe中的test_power_init函数如下:
- static int __init test_power_init(struct platform_device *pdev)
- {
- int i;
- int ret;
- pbat = kmalloc(sizeof(struct test_adc_bat), GFP_KERNEL);
- if(pbat == NULL)
- {
- printk(KERN_ERR "%s: kmalloc failed\n", __func__);
- return -1;
- }
- memset(pbat, 0, sizeof(struct test_adc_bat));
- /* init struct test_adc_bat */
- pbat->adc_client = NULL;
- pbat->ac_online_pin = S5PV210_GPJ2(0);
- pbat->charge_over_pin = S5PV210_GPH2(0);
- pbat->supply_timer_time = 1500; /* 500 ms */
- pbat->adc_channel = 1;
- /* init ac online pin */
- ret = gpio_request(pbat->ac_online_pin, "ac_online_pin");
- if(ret < 0)
- {
- printk(KERN_ERR "%s: request ac online pin failed!\n", __func__);
- return -1;
- }
- /* make gpio to input */
- ret = s3c_gpio_cfgpin(pbat->ac_online_pin, S3C_GPIO_SFN(0));
- if(ret < 0)
- {
- printk(KERN_ERR "%s: config gpio to input failed!\n", __func__);
- goto gpio_failed;
- }
- ret = gpio_direction_input(pbat->ac_online_pin);
- if(ret != 0)
- {
- printk(KERN_ERR "%s: config gpio to input failed!\n", __func__);
- goto gpio_failed;
- }
- /* init charge over pin */
- ret = gpio_request(pbat->charge_over_pin, "charge_over_pin");
- if(ret < 0)
- {
- printk(KERN_ERR "%s: request charge over pin failed!\n", __func__);
- return -1;
- }
- /* make gpio to input */
- ret = s3c_gpio_cfgpin(pbat->charge_over_pin, S3C_GPIO_SFN(0));
- if(ret < 0)
- {
- printk(KERN_ERR "%s: config gpio to input failed!\n", __func__);
- goto gpio_failed;
- }
- ret = gpio_direction_input(pbat->charge_over_pin);
- if(ret != 0)
- {
- printk(KERN_ERR "%s: config gpio to input failed!\n", __func__);
- goto gpio_failed;
- }
- /* init timer, init supply_timer(timer_list members) */
- supply_timer.expires = jiffies + msecs_to_jiffies(pbat->supply_timer_time);
- setup_timer(&supply_timer, supply_timer_func, 0);
- /* add timer to system and start it */
- add_timer(&supply_timer);
- for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) {
- ret = power_supply_register(&pdev->dev, &test_power_supplies[i]);
- if (ret) {
- pr_err("%s: failed to register %s\n", __func__,
- test_power_supplies[i].name);
- goto failed;
- }
- }
- return 0;
- failed:
- while (--i >= 0)
- power_supply_unregister(&test_power_supplies[i]);
- gpio_failed:
- gpio_free(pbat->ac_online_pin);
- gpio_free(pbat->charge_over_pin);
- del_timer_sync(&supply_timer);
- kfree(pbat);
- return ret;
- }
复制代码
其中
- struct test_adc_bat
- {
- struct s3c_adc_client *adc_client; /* for adc */
- unsigned long ac_online_pin; /* GPJ2_0 */
- unsigned long charge_over_pin; /* GPH2_0 */
- unsigned int supply_timer_time; /* msecs, default 500ms, for supply_timer */
- unsigned int adc_channel; /* ad chinnel: 0 ~ 9 => AIN0 ~ AIN9 */
- };
- static struct test_adc_bat *pbat = NULL;
- static struct timer_list supply_timer;
复制代码
test_adc_bat , supply_timer,adc_base_addr 都是全局变量。
IRQ如下:
- static struct resource adc_irq_res =
- {
- .start = IRQ_ADC,
- .end = IRQ_ADC,
- .flags = IORESOURCE_IRQ,
- };
复制代码
我在定时器函数中调用test_bat_adc_convert 想得到通道1的AD值,test_bat_adc_convert 函数如下:
- static unsigned int test_bat_adc_convert(int ch)
- {
- unsigned int ret = 0;
- unsigned long dat0 = 0;
- unsigned long dat1 = 2000;
- writel((readl(adc_base_addr + S3C_ADCCON) | S3C_ADCCON_PRSCEN) & ~S3C_ADCCON_STDBM, adc_base_addr + S3C_ADCCON);
- /* select the ch in mutx */
- writel((ch & 0x0f), adc_base_addr + S3C_ADCMUX);
- udelay(20);
- /* start adc */
- writel(readl(adc_base_addr + S3C_ADCCON) | S3C_ADCCON_READ_START, adc_base_addr + S3C_ADCCON);
- readl(adc_base_addr + S3C_ADCDAT0);
- do{
- dat0 = readl(adc_base_addr + S3C_ADCCON);
- udelay(100);
- } while(!(dat0 & S3C_ADCCON_ECFLG));
- dat1 = readl(adc_base_addr + S3C_ADCDAT0);
- writel((readl(adc_base_addr + S3C_ADCCON) | S3C_ADCCON_STDBM) & ~S3C_ADCCON_PRSCEN, adc_base_addr + S3C_ADCCON);
- return (dat1 & S3C_ADCDAT0_XPDATA_MASK_12BIT);
- }
复制代码
得到的结果是:整个内核都停在 test_bat_adc_convert 中的 do{....}while(...) 中,不知道我什么地方设置错了,该怎么对ADC进行设置 才能读到ADC的采样值?
我感觉ADC没有启动,但从得到 信息可以看到ADC是配置是没什么错误的,不知道我什么地方没有配置正确出现了这种情况,还请Cavin指教。。。。。。
|
|