Esempio n. 1
0
/* 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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;
}
Esempio n. 6
0
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;
}