/* RT-Thread Device Interface */ static rt_err_t rtgui_touch_init(rt_device_t dev) { /* init touch screen structure */ rt_memset(&ts, 0, sizeof(struct s3c2410ts)); ts.delay = 50000; ts.presc = 9; ts.shift = 2; ts.count = 0; ts.xp = ts.yp = 0; ADCCON = S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(ts.presc); ADCDLY = ts.delay; ADCTSC = WAIT4INT(0); rt_hw_interrupt_install(INTADC, rt_touch_handler, RT_NULL); rt_hw_interrupt_umask(INTADC); /* clear interrupt */ INTPND |= (1ul << INTADC); SUBSRCPND |= BIT_SUB_TC; SUBSRCPND |= BIT_SUB_ADC; /* install interrupt handler */ INTSUBMSK &= ~BIT_SUB_ADC; INTSUBMSK &= ~BIT_SUB_TC; touch->first_down_report = RT_TRUE; return RT_EOK; }
static int s3c2410ts_resume(struct platform_device *pdev) { struct s3c2410_ts_mach_info *info = ( struct s3c2410_ts_mach_info *)pdev->dev.platform_data; clk_enable(adc_clock); mdelay(1); ts_filter_chain_clear(ts.chain); enable_irq(IRQ_ADC); enable_irq(IRQ_TC); if ((info->presc&0xff) > 0) writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF), base_addr+S3C2410_ADCCON); else writel(0,base_addr+S3C2410_ADCCON); /* Initialise registers */ if ((info->delay & 0xffff) > 0) writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY); writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC); return 0; }
/* 设置 ADC 时钟的预分频值 */ static inline void set_adc_prescaler(struct ts_data *ts, int value) { unsigned int data; data = ADCCON(ts); /* 读原值 */ data |= S3C2410_ADCCON_PRSCEN; /* 设置预分频使能标志位 */ data &= ~S3C2410_ADCCON_PRSCVLMASK; /* 清空原来的预分频值 */ data |= S3C2410_ADCCON_PRSCVL(value); /* 设置新的预分频值 */ wADCCON(ts, data); /* 写新值 */ }
void adc_init(void) { int user_data = 0; unsigned int adc_con = 0; /* set register value*/ /* 50,000,000/(9+1) | enable select = 0 | stat by set 1 to bit 0 | set to normal model*/ adc_con = (S3C2410_ADCCON_PRSCVL(9) | S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_SELMUX(0)); printk("[%x]\n", adc_con); /* write to register*/ writel(readl(S3C2410_CLKCON) | S3C2410_CLKCON_ADC,S3C2410_CLKCON); writel(adc_con, (S3C2410_ADCCON + SYS_ADDRESS)); #ifdef DEBUG printk("[%x]\n", readl(S3C2410_ADCCON + SYS_ADDRESS)); #endif // user_data = adc_test(); printk("%d", user_data); }
static int __init s3c_adc_probe(struct platform_device *pdev) { struct resource *res; struct s3c_adc_cfg *plat_data; struct device *dev; int ret; int size; res = platform_get_resource(pdev,IORESOURCE_MEM,0); dev = &pdev->dev; if(res == NULL){ dev_err(dev,"no memory resource specified\n"); return -ENOENT; } size = (res->end - res->start) + 1; adc_mem = request_mem_region(res->start, size, pdev->name); if(adc_mem == NULL){ dev_err(dev, "failed to get memory region\n"); ret = -ENOENT; goto err_req; } base_addr = ioremap(res->start,size); if(base_addr == NULL){ dev_err(dev,"fail to ioremap() region\n"); ret = -ENOENT; goto err_map; } adc_clock = clk_get(&pdev->dev, "adc"); if(IS_ERR(adc_clock)){ dev_err(dev,"failed to fine adc clock wource\n"); ret = PTR_ERR(adc_clock); goto err_clk; } clk_enable(adc_clock); /* read platform data from device struct */ plat_data = s3c_adc_get_platdata(&pdev->dev); if ((plat_data->presc&0xff) > 0) writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(plat_data->presc&0xFF), base_addr+S3C2410_ADCCON); else writel(0, base_addr+S3C2410_ADCCON); /* Initialise registers */ if ((plat_data->delay&0xffff) > 0) writel(plat_data->delay & 0xffff, base_addr+S3C2410_ADCDLY); if (plat_data->resolution== 12) { writel(readl(base_addr+S3C2410_ADCCON)|S3C6410_ADCCON_RESSEL_12BIT, base_addr+S3C2410_ADCCON); } ret = misc_register(&s3c_adc_miscdev); if (ret) { printk (KERN_ERR "cannot register miscdev on minor=%d (%d)\n", ADC_MINOR, ret); goto err_clk; } printk(KERN_INFO "S3C64XX ADC driver successfully probed !\n"); return 0; err_clk: clk_disable(adc_clock); clk_put(adc_clock); err_map: iounmap(base_addr); err_req: release_resource(adc_mem); kfree(adc_mem); return ret; }
static int __init s3c2410ts_probe(struct platform_device *pdev) { int rc; struct s3c2410_ts_mach_info *info; struct input_dev *input_dev; int ret = 0; dev_info(&pdev->dev, "Starting\n"); info = (struct s3c2410_ts_mach_info *)pdev->dev.platform_data; if (!info) { dev_err(&pdev->dev, "Hm... too bad: no platform data for ts\n"); return -EINVAL; } #ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG printk(DEBUG_LVL "Entering s3c2410ts_init\n"); #endif adc_clock = clk_get(NULL, "adc"); if (!adc_clock) { dev_err(&pdev->dev, "failed to get adc clock source\n"); return -ENOENT; } clk_enable(adc_clock); #ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG printk(DEBUG_LVL "got and enabled clock\n"); #endif base_addr = ioremap(S3C2410_PA_ADC,0x20); if (base_addr == NULL) { dev_err(&pdev->dev, "Failed to remap register block\n"); ret = -ENOMEM; goto bail0; } /* If we acutally are a S3C2410: Configure GPIOs */ if (!strcmp(pdev->name, "s3c2410-ts")) s3c2410_ts_connect(); if ((info->presc & 0xff) > 0) writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF), base_addr + S3C2410_ADCCON); else writel(0, base_addr+S3C2410_ADCCON); /* Initialise registers */ if ((info->delay & 0xffff) > 0) writel(info->delay & 0xffff, base_addr + S3C2410_ADCDLY); writel(WAIT4INT(0), base_addr + S3C2410_ADCTSC); /* Initialise input stuff */ memset(&ts, 0, sizeof(struct s3c2410ts)); input_dev = input_allocate_device(); if (!input_dev) { dev_err(&pdev->dev, "Unable to allocate the input device\n"); ret = -ENOMEM; goto bail1; } ts.dev = input_dev; ts.dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); ts.dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0); input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0); input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0); ts.dev->name = s3c2410ts_name; ts.dev->id.bustype = BUS_RS232; ts.dev->id.vendor = 0xDEAD; ts.dev->id.product = 0xBEEF; ts.dev->id.version = S3C2410TSVERSION; ts.state = TS_STATE_STANDBY; ts.event_fifo = kfifo_alloc(TS_EVENT_FIFO_SIZE, GFP_KERNEL, NULL); if (IS_ERR(ts.event_fifo)) { ret = -EIO; goto bail2; } /* create the filter chain set up for the 2 coordinates we produce */ ts.chain = ts_filter_chain_create(pdev, info->filter_config, 2); if (IS_ERR(ts.chain)) goto bail2; ts_filter_chain_clear(ts.chain); /* Get irqs */ if (request_irq(IRQ_ADC, stylus_action, IRQF_SAMPLE_RANDOM, "s3c2410_action", ts.dev)) { dev_err(&pdev->dev, "Could not allocate ts IRQ_ADC !\n"); iounmap(base_addr); ret = -EIO; goto bail3; } if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM, "s3c2410_action", ts.dev)) { dev_err(&pdev->dev, "Could not allocate ts IRQ_TC !\n"); free_irq(IRQ_ADC, ts.dev); iounmap(base_addr); ret = -EIO; goto bail4; } dev_info(&pdev->dev, "Successfully loaded\n"); /* All went ok, so register to the input system */ rc = input_register_device(ts.dev); if (rc) { ret = -EIO; goto bail5; } return 0; bail5: free_irq(IRQ_TC, ts.dev); free_irq(IRQ_ADC, ts.dev); clk_disable(adc_clock); iounmap(base_addr); disable_irq(IRQ_TC); bail4: disable_irq(IRQ_ADC); bail3: ts_filter_chain_destroy(ts.chain); kfifo_free(ts.event_fifo); bail2: input_unregister_device(ts.dev); bail1: iounmap(base_addr); bail0: return ret; }