Exemplo n.º 1
0
static void s3c2410_adc_stylus_action(void)
{
	rt_uint32_t data0;
	rt_uint32_t data1;

	data0 = ADCDAT0;
	data1 = ADCDAT1;

	ts.xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;
	ts.yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;
	ts.count ++;

	if (ts.count < (1<<ts.shift))
	{
		ADCTSC = S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST;
		ADCCON |= S3C2410_ADCCON_ENABLE_START;
	}
	else
	{
		if (touch->first_down_report)
		{
			report_touch_input(1);
			ts.xp = 0;
			ts.yp = 0;
			ts.count = 0;
			touch->first_down_report = 0;
		}
		/* start timer */
		rt_timer_start(touch->poll_timer);
		ADCTSC = WAIT4INT(1);
	}

	SUBSRCPND |= BIT_SUB_ADC;
}
Exemplo n.º 2
0
static void s3c2410_intc_stylus_updown(void)
{
	rt_uint32_t data0;
	rt_uint32_t data1;
	int updown;

	data0 = ADCDAT0;
	data1 = ADCDAT1;

	updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));

	/* rt_kprintf("stylus: %s\n", updown? "down" : "up"); */

	if (updown) 
	{
		touch_timer_fire(0);
	}
	else
	{
		/* stop timer */
		rt_timer_stop(touch->poll_timer);
		touch->first_down_report = RT_TRUE;
		if (ts.xp >= 0 && ts.yp >= 0)
		{
			report_touch_input(updown);
		}
		ts.count = 0;
		ADCTSC = WAIT4INT(0);
	}

	SUBSRCPND |= BIT_SUB_TC;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}
static irqreturn_t stylus_action(int irqno, void *param)
{
	unsigned long data0;
	unsigned long data1;

	data0 = readl(ts_base + S3C_ADCDAT0);
	data1 = readl(ts_base + S3C_ADCDAT1);

	if (ts->resol_bit == 12) {
		ts->xp += S3C_ADCDAT0_XPDATA_MASK_12BIT -
			(data0 & S3C_ADCDAT0_XPDATA_MASK_12BIT);
		ts->yp += data1 & S3C_ADCDAT1_YPDATA_MASK_12BIT;
	} else {
		ts->xp += data0 & S3C_ADCDAT0_XPDATA_MASK;
		ts->yp += data1 & S3C_ADCDAT1_YPDATA_MASK;
	}

	ts->count++;

	if (ts->count < (1<<ts->shift)) {
		writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST,
				ts_base + S3C_ADCTSC);
		writel(readl(ts_base + S3C_ADCCON) | S3C_ADCCON_ENABLE_START,
				ts_base + S3C_ADCCON);
	} else {
		mod_timer(&touch_timer, jiffies + 1);
		writel(WAIT4INT(1), ts_base + S3C_ADCTSC);
	}

	if (ts->s3c_adc_con == ADC_TYPE_2) {
		__raw_writel(0x0, ts_base+S3C_ADCCLRWK);
		__raw_writel(0x0, ts_base+S3C_ADCCLRINT);
	}
	return IRQ_HANDLED;
}
Exemplo n.º 6
0
static irqreturn_t stylus_updown(int irq, void *dev_id)
{
	unsigned long data0;
	unsigned long data1;
	int event_type;

	data0 = readl(base_addr+S3C2410_ADCDAT0);
	data1 = readl(base_addr+S3C2410_ADCDAT1);

	ts.is_down = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) &&
					    (!(data1 & S3C2410_ADCDAT0_UPDOWN));

	event_type = ts.is_down ? 'D' : 'U';

	if (unlikely(__kfifo_put(ts.event_fifo, (unsigned char *)&event_type,
		     sizeof(int)) != sizeof(int))) /* should not happen */
		printk(KERN_ERR __FILE__": stylus_updown lost event!\n");

	if (ts.is_down)
		s3c2410_ts_start_adc_conversion();
	else
		writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);

	mod_timer(&event_send_timer, jiffies + 1);

	return IRQ_HANDLED;
}
Exemplo n.º 7
0
static irqreturn_t stylus_action(int irq, void *dev_id)
{
	int buf[3];

	/* Grab the ADC results. */
	buf[1] = readl(base_addr + S3C2410_ADCDAT0) &
		       S3C2410_ADCDAT0_XPDATA_MASK;
	buf[2] = readl(base_addr + S3C2410_ADCDAT1) &
		       S3C2410_ADCDAT1_YPDATA_MASK;

	switch (ts_filter_chain_feed(ts.chain, &buf[1])) {
	case 0:
		/* The filter wants more points. */
		s3c2410_ts_start_adc_conversion();
		return IRQ_HANDLED;
	case 1:
		/* We have a point from the filters or no filtering enabled. */
		buf[0] = 'P';
		break;
	default:
		printk(KERN_ERR __FILE__
		       ":%d Invalid ts_filter_chain_feed return value.\n",
		       __LINE__);
	case -1:
		/* Error. Ignore the event. */
		ts_filter_chain_clear(ts.chain);
		writel(WAIT4INT(1), base_addr + S3C2410_ADCTSC);
		return IRQ_HANDLED;
	};

	if (unlikely(__kfifo_put(ts.event_fifo, (unsigned char *)buf,
		     sizeof(int) * 3) != sizeof(int) * 3))
		printk(KERN_ERR __FILE__":stylus_action bug.\n");

	writel(WAIT4INT(1), base_addr + S3C2410_ADCTSC);
	mod_timer(&event_send_timer, jiffies + 1);

	return IRQ_HANDLED;
}
Exemplo n.º 8
0
static int s3c_ts_resume(struct platform_device *pdev)
{
	clk_enable(ts_clock);

	writel(adccon, ts_base+S3C_ADCCON);
	writel(adctsc, ts_base+S3C_ADCTSC);
	writel(adcdly, ts_base+S3C_ADCDLY);
	writel(WAIT4INT(0), ts_base+S3C_ADCTSC);

	enable_irq(IRQ_ADC1);
	enable_irq(IRQ_PENDN1);

	return 0;
}
Exemplo n.º 9
0
static irqreturn_t stylus_action(int irqno, void *param)
{
	unsigned long data0;
	unsigned long data1;

	data0 = readl(ts_base+S3C_ADCDAT0);
	data1 = readl(ts_base+S3C_ADCDAT1);

	if (ts->resol_bit == 12) {
#if defined(CONFIG_TOUCHSCREEN_NEW)
		ts->yp += S3C_ADCDAT0_XPDATA_MASK_12BIT - (data0 & S3C_ADCDAT0_XPDATA_MASK_12BIT);
		ts->xp += S3C_ADCDAT1_YPDATA_MASK_12BIT - (data1 & S3C_ADCDAT1_YPDATA_MASK_12BIT);
#else /* CONFIG_TOUCHSCREEN_NEW */
#ifndef CONFIG_CPU_S5PV210_EVT1
		ts->xp += data0 & S3C_ADCDAT0_XPDATA_MASK_12BIT;
#else /* !CONFIG_CPU_S5PV210_EVT1 */
#if defined(CONFIG_MACH_MANGO210)
		ts->xp += data0 & S3C_ADCDAT0_XPDATA_MASK_12BIT;
#else
		ts->xp += S3C_ADCDAT0_XPDATA_MASK_12BIT - (data0 & S3C_ADCDAT0_XPDATA_MASK_12BIT);
#endif
#endif /* !CONFIG_CPU_S5PV210_EVT1 */
		ts->yp += data1 & S3C_ADCDAT1_YPDATA_MASK_12BIT;
#endif /* CONFIG_TOUCHSCREEN_NEW */
	} else {
#if defined(CONFIG_TOUCHSCREEN_NEW)
		ts->yp += S3C_ADCDAT0_XPDATA_MASK - (data0 & S3C_ADCDAT0_XPDATA_MASK);
		ts->xp += S3C_ADCDAT1_YPDATA_MASK - (data1 & S3C_ADCDAT1_YPDATA_MASK);
#else /* CONFIG_TOUCHSCREEN_NEW */
		ts->xp += data0 & S3C_ADCDAT0_XPDATA_MASK;
		ts->yp += data1 & S3C_ADCDAT1_YPDATA_MASK;
#endif /* CONFIG_TOUCHSCREEN_NEW */
	}

	ts->count++;

	if (ts->count < (1<<ts->shift)) {
		writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts_base+S3C_ADCTSC);
		writel(readl(ts_base+S3C_ADCCON) | S3C_ADCCON_ENABLE_START, ts_base+S3C_ADCCON);
	} else {
		mod_timer(&touch_timer, jiffies+1);
		writel(WAIT4INT(1), ts_base+S3C_ADCTSC);
	}

	if (ts->s3c_adc_con == ADC_TYPE_2) {
		__raw_writel(0x0, ts_base+S3C_ADCCLRWK);
		__raw_writel(0x0, ts_base+S3C_ADCCLRINT);
	}
	return IRQ_HANDLED;
}
Exemplo n.º 10
0
static int s3c_ts_resume(struct platform_device *pdev)
{
	clk_enable(ts_clock);

#ifdef CONFIG_TOUCHSCREEN_USEAD1	
	writel(readl(ts_base0 + S3C_ADCCON) | 0x20000, ts_base0 + S3C_ADCCON);
#endif

	writel(adccon, ts_base+S3C_ADCCON);
	writel(adctsc, ts_base+S3C_ADCTSC);
	writel(adcdly, ts_base+S3C_ADCDLY);
	writel(WAIT4INT(0), ts_base+S3C_ADCTSC);

	enable_irq(IRQ_ADC);
	enable_irq(IRQ_PENDN);

	return 0;
}
static void touch_timer_fire(unsigned long data)
{
	unsigned long data0, data1;
	int updown;
	int x, y;

    s3c_adc_lock();

	data0 = readl(ts_base+S3C_ADCDAT0);
	data1 = readl(ts_base+S3C_ADCDAT1);
	updown = (!(data0 & S3C_ADCDAT0_UPDOWN)) && (!(data1 & S3C_ADCDAT1_UPDOWN));

	if (updown) {
		if (ts->count) {
			x = (int)ts->xp/ts->count;
			y = (int)ts->yp/ts->count;

			input_report_abs(ts->dev, ABS_X, x);
			input_report_abs(ts->dev, ABS_Y, y);
			input_report_abs(ts->dev, ABS_PRESSURE, 1);
			input_report_key(ts->dev, BTN_TOUCH, 1);
			input_sync(ts->dev);
		}

		ts->xp = 0;
		ts->yp = 0;
		ts->count = 0;

		writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts_base + S3C_ADCTSC);
		writel(readl(ts_base+S3C_ADCCON) | S3C_ADCCON_ENABLE_START, ts_base + S3C_ADCCON);
	} else {
		ts->count = 0;

		input_report_abs(ts->dev, ABS_PRESSURE, 0);
		input_report_key(ts->dev, BTN_TOUCH, 0);
		input_sync(ts->dev);

		writel(WAIT4INT(0), ts_base+S3C_ADCTSC);
	}

    s3c_adc_unlock();
}
Exemplo n.º 12
0
static void touch_timer_fire(unsigned long data)
{
	unsigned long data0;
	unsigned long data1;
	int updown;
#ifdef CONFIG_ANDROID
	int x,y;
#ifndef CONFIG_CPU_S5PV210_EVT1

#ifdef CONFIG_TOUCHSCREEN_NEW
	int a0,a1,a2,a3,a4,a5,a6;

	a0=11;
	a1=3004;
	a2=-9542528;
	a3=-4300;
	a4=4;
	a5=61817184;
	a6=65536;
#else /* CONFIG_TOUCHSCREEN_NEW */
	a0=5171;
	a1=9;
	a2=-17497920;
	a3=-12;
	a4=-4659;
	a5=52871808;
	a6=65536;
#endif /* CONFIG_TOUCHSCREEN_NEW */
#endif /* !CONFIG_CPU_S5PV210_EVT1 */
#endif /* CONFIG_ANDROID */

	data0 = readl(ts_base+S3C_ADCDAT0);
	data1 = readl(ts_base+S3C_ADCDAT1);

	updown = (!(data0 & S3C_ADCDAT0_UPDOWN)) && (!(data1 & S3C_ADCDAT1_UPDOWN));

	if (updown) {
		if (ts->count) {

#ifdef CONFIG_TOUCHSCREEN_S3C_DEBUG
			{
				struct timeval tv;
				do_gettimeofday(&tv);
				printk(KERN_INFO "T: %06d, X: %03ld, Y: %03ld\n", (int)tv.tv_usec, ts->xp, ts->yp);
			}
#endif

#ifdef CONFIG_ANDROID
#ifndef CONFIG_CPU_S5PV210_EVT1
			x=(int) ts->xp;
			y=(int) ts->yp;

			ts->xp=(long) ((a2+(a0*x)+(a1*y))/a6) * 800/480;
			ts->yp=(long) ((a5+(a3*x)+(a4*y))/a6) * 480/800;
			//printk("x=%d, y=%d\n",(int) ts->xp,(int) ts->yp);

			if (ts->xp!=ts->xp_old || ts->yp!=ts->yp_old) {
				input_report_abs(ts->dev, ABS_X, ts->xp);
				input_report_abs(ts->dev, ABS_Y, ts->yp);
				input_report_abs(ts->dev, ABS_Z, 0);

				input_report_key(ts->dev, BTN_TOUCH, 1);
				//          input_report_abs(ts->dev, ABS_PRESSURE, 1);
				input_sync(ts->dev);
			}
			ts->xp_old=ts->xp;
			ts->yp_old=ts->yp;
#else /* !CONFIG_CPU_S5PV210_EVT1 */
			x=(int) ts->xp/ts->count;
			y=(int) ts->yp/ts->count;
#if defined(CONFIG_FB_S3C_LTE480WV)
			y = 4000 - y;
#endif /* CONFIG_FB_S3C_LTE480WV */
			//printk("Cordinates x=%d, y=%d\n",(int) x,(int) y);
			input_report_abs(ts->dev, ABS_X, x);
			input_report_abs(ts->dev, ABS_Y, y);
			input_report_abs(ts->dev, ABS_Z, 0);
			input_report_key(ts->dev, BTN_TOUCH, 1);
			input_sync(ts->dev);
#endif /* !CONFIG_CPU_S5PV210_EVT1 */
#else /* CONFIG_ANDROID */
			input_report_abs(ts->dev, ABS_X, ts->xp);
			input_report_abs(ts->dev, ABS_Y, ts->yp);

			input_report_key(ts->dev, BTN_TOUCH, 1);
			input_report_abs(ts->dev, ABS_PRESSURE, 1);
			input_sync(ts->dev);
#endif /* CONFIG_ANDROID */
		}

		ts->xp = 0;
		ts->yp = 0;
		ts->count = 0;

		writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts_base+S3C_ADCTSC);
		writel(readl(ts_base+S3C_ADCCON) | S3C_ADCCON_ENABLE_START, ts_base+S3C_ADCCON);
	} else {
		ts->count = 0;
#ifdef CONFIG_ANDROID
#ifdef CONFIG_CPU_S5PV210_EVT1
		input_report_abs(ts->dev, ABS_X, ts->xp);
		input_report_abs(ts->dev, ABS_Y, ts->yp);
#else /* CONFIG_CPU_S5PV210_EVT1 */
		input_report_abs(ts->dev, ABS_X, ts->xp_old);
		input_report_abs(ts->dev, ABS_Y, ts->yp_old);
#endif /* CONFIG_CPU_S5PV210_EVT1 */
		input_report_abs(ts->dev, ABS_Z, 0);
#endif /* CONFIG_ANDROID */
		input_report_key(ts->dev, BTN_TOUCH, 0);
#ifndef CONFIG_ANDROID
		input_report_abs(ts->dev, ABS_PRESSURE, 0);
#endif /* !CONFIG_ANDROID */
		input_sync(ts->dev);

		writel(WAIT4INT(0), ts_base+S3C_ADCTSC);
	}
}
Exemplo n.º 13
0
/*
 * The functions for inserting/removing us as a module.
 */
static int __init s3c_ts_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct device *dev;
	struct input_dev *input_dev;
	struct s3c_ts_mach_info *s3c_ts_cfg;
	int ret, size;
	int irq_flags = 0;
#ifdef CONFIG_TOUCHSCREEN_ADC1
	int tmp;
#endif


	dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(dev, "no memory resource specified\n");
		return -ENOENT;
	}

	size = (res->end - res->start) + 1;
	ts_mem = request_mem_region(res->start, size, pdev->name);
	if (ts_mem == NULL) {
		dev_err(dev, "failed to get memory region\n");
		ret = -ENOENT;
		goto err_req;
	}

	ts_base = ioremap(res->start, size);
#ifdef CONFIG_TOUCHSCREEN_ADC1
	//Set TSADCCON0 bit 17
	tmp = readl(ts_base);
	tmp |= (0x01 << 17);
	writel(tmp, ts_base);

	//remap ts_base to 0xE1701000
	iounmap(ts_base);
	release_resource(ts_mem);

	ts_mem = request_mem_region(res->start + 0x1000, size, pdev->name);
	ts_base = ioremap(res->start + 0x1000, size);
	printk("remap to 0xE1701000. done\n");
#endif
	
	if (ts_base == NULL) {
		dev_err(dev, "failed to ioremap() region\n");
		ret = -EINVAL;
		goto err_map;
	}

	ts_clock = clk_get(&pdev->dev, "adc");
	if (IS_ERR(ts_clock)) {
		dev_err(dev, "failed to find watchdog clock source\n");
		ret = PTR_ERR(ts_clock);
		goto err_clk;
	}

	clk_enable(ts_clock);

	s3c_ts_cfg = s3c_ts_get_platdata(&pdev->dev);
	if ((s3c_ts_cfg->presc & 0xff) > 0)
		writel(S3C_ADCCON_PRSCEN | S3C_ADCCON_PRSCVL(s3c_ts_cfg->presc & 0xFF), ts_base+S3C_ADCCON);
	else
		writel(0, ts_base + S3C_ADCCON);

	/* Initialise registers */
	if ((s3c_ts_cfg->delay & 0xffff) > 0)
		writel(s3c_ts_cfg->delay & 0xffff, ts_base + S3C_ADCDLY);

	if (s3c_ts_cfg->resol_bit == 12) {
		switch (s3c_ts_cfg->s3c_adc_con) {
		case ADC_TYPE_2:
			writel(readl(ts_base + S3C_ADCCON) |
					S3C_ADCCON_RESSEL_12BIT,
					ts_base + S3C_ADCCON);
			break;

		case ADC_TYPE_1:
			writel(readl(ts_base + S3C_ADCCON) |
					S3C_ADCCON_RESSEL_12BIT_1,
					ts_base + S3C_ADCCON);
			break;

		default:
			dev_err(dev, "this type of AP isn't supported !\n");
			break;
		}
	}

	writel(WAIT4INT(0), ts_base + S3C_ADCTSC);

	ts = kzalloc(sizeof(struct s3c_ts_info), GFP_KERNEL);

	input_dev = input_allocate_device();
	if (!input_dev) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	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);

	if (s3c_ts_cfg->resol_bit == 12) {
		input_set_abs_params(ts->dev, ABS_X, 0, 0xFFF, 0, 0);
		input_set_abs_params(ts->dev, ABS_Y, 0, 0xFFF, 0, 0);
	} else {
		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);

	sprintf(ts->phys, "input-ts");

	ts->dev->name = s3c_ts_name;
	ts->dev->phys = ts->phys;
	ts->dev->id.bustype = BUS_RS232;
	ts->dev->id.vendor = 0xDEAD;
	ts->dev->id.product = 0xBEEF;
	ts->dev->id.version = S3C_TSVERSION;

	ts->shift = s3c_ts_cfg->oversampling_shift;
	ts->resol_bit = s3c_ts_cfg->resol_bit;
	ts->s3c_adc_con = s3c_ts_cfg->s3c_adc_con;

	/* For IRQ_PENDUP */
	ts_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (ts_irq == NULL) {
		dev_err(dev, "no irq resource specified\n");
		ret = -ENOENT;
		goto err_irq;
	}

	ret = request_irq(ts_irq->start, stylus_updown, irq_flags,
			"s3c_updown", ts);
	if (ret != 0) {
		dev_err(dev, "s3c_ts.c: Could not allocate ts IRQ_PENDN !\n");
		ret = -EIO;
		goto err_irq;
	}

	/* For IRQ_ADC */
	ts_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	if (ts_irq == NULL) {
		dev_err(dev, "no irq resource specified\n");
		ret = -ENOENT;
		goto err_irq;
	}

	ret = request_irq(ts_irq->start, stylus_action, irq_flags,
			"s3c_action", ts);
	if (ret != 0) {
		dev_err(dev, "s3c_ts.c: Could not allocate ts IRQ_ADC !\n");
		ret =  -EIO;
		goto err_irq;
	}

	printk(KERN_INFO "%s got loaded successfully : %d bits\n",
			s3c_ts_name, s3c_ts_cfg->resol_bit);

	/* All went ok, so register to the input system */
	ret = input_register_device(ts->dev);
	if (ret) {
		dev_err(dev, "Could not register input device(touchscreen)!\n");
		ret = -EIO;
		goto fail;
	}

	return 0;

fail:
	free_irq(ts_irq->start, ts->dev);
	free_irq(ts_irq->end, ts->dev);

err_irq:
	input_free_device(input_dev);
	kfree(ts);

err_alloc:
	clk_disable(ts_clock);
	clk_put(ts_clock);

err_clk:
	iounmap(ts_base);

err_map:
	release_resource(ts_mem);
	kfree(ts_mem);

err_req:
	return ret;
}
Exemplo n.º 14
0
static void touch_timer_fire(unsigned long data)
{
	unsigned long data0;
	unsigned long data1;
	int updown;
	unsigned long dist;

#ifdef CONFIG_S3CTS_ANDROID
	unsigned long xtemp, ytemp;
#endif


	data0 = readl(ts_base+S3C_ADCDAT0);
	data1 = readl(ts_base+S3C_ADCDAT1);

	updown = (!(data0 & S3C_ADCDAT0_UPDOWN)) && (!(data1 & S3C_ADCDAT1_UPDOWN));

	if (updown) {
		if (ts->count) {

#ifdef CONFIG_TOUCHSCREEN_S3C_DEBUG
			{
				struct timeval tv;
				do_gettimeofday(&tv);
				printk(KERN_INFO "T: %06d, X: %03ld, Y: %03ld\n", (int)tv.tv_usec, ts->xp, ts->yp);
			}
#endif

// If you want calibrate touch screen, #if set 1 to 0.
#if 1
			xtemp = ts->xp;
			ytemp = ts->yp;

			if( !last_flag )
			{
				last = ts;
				last_flag = 1;
			}	
		
			dist = sqr( xtemp - last->xp ) + sqr( ytemp - last->yp );
			if ( dist > delta )
			{
				return;
			}

			ts->xp = ( pointercal[2] + pointercal[0]*xtemp + pointercal[1]*ytemp ) / pointercal[6];
			ts->yp = ( pointercal[5] + pointercal[3]*xtemp + pointercal[4]*ytemp ) / pointercal[6];

#ifdef CONFIG_ANDROID_TOUCHSCREEN_S3C_DEBUG
			printk("pre: x, y = %ld, %ld\n", ts->xp, ts->yp);
#endif
			if( ts->xp > 65500 ) ts->xp = 1;
			if( ts->xp > ANDROID_TS_RESOLUTION_X )
				ts->xp = ANDROID_TS_RESOLUTION_X-1;
			else if(ts->xp < 0)
			    ts->xp = 1;
			
			if( ts->yp > ANDROID_TS_RESOLUTION_Y  )
			    ts->yp = ANDROID_TS_RESOLUTION_Y-1;
			else if(ts->yp < 0)
			    ts->yp = 1;
			
			if( (ts->xp <= ANDROID_TS_RESOLUTION_X-1) && (ts->xp >= 1) )
			{
			    input_report_abs(ts->dev, ABS_X, ts->xp);
			    input_report_abs(ts->dev, ABS_Y, ts->yp);
			
			    input_report_key(ts->dev, BTN_TOUCH, 1);
			    input_report_abs(ts->dev, ABS_PRESSURE, 1);
			    input_sync(ts->dev);
#ifdef CONFIG_ANDROID_TOUCHSCREEN_S3C_DEBUG
			    printk("x, y = %ld, %ld\n", ts->xp, ts->yp);
#endif
			}
#else
			input_report_abs(ts->dev, ABS_X, ts->xp);
			input_report_abs(ts->dev, ABS_Y, ts->yp);

			input_report_key(ts->dev, BTN_TOUCH, 1);
			input_report_abs(ts->dev, ABS_PRESSURE, 1);
			input_sync(ts->dev);
			printk("x, y = %d, %d\n", ts->xp, ts->yp);
#endif
		}

		ts->xp = 0;
		ts->yp = 0;
		ts->count = 0;

		writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts_base + S3C_ADCTSC);
		writel(readl(ts_base+S3C_ADCCON) | S3C_ADCCON_ENABLE_START, ts_base + S3C_ADCCON);

	}
	else {

		ts->count = 0;
		last_flag = 0;

//		input_report_abs(ts->dev, ABS_X, ts->xp);
//		input_report_abs(ts->dev, ABS_Y, ts->yp);
//		input_report_abs(ts->dev, ABS_Z, 0);
//		input_report_key(ts->dev, BTN_TOUCH, 0);
//		input_sync(ts->dev);
		input_report_key(ts->dev, BTN_TOUCH, 0);
		input_report_abs(ts->dev, ABS_PRESSURE, 0);
		input_sync(ts->dev);

		writel(WAIT4INT(0), ts_base+S3C_ADCTSC);
	}
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
static void touch_timer_fire(unsigned long data)
{
	unsigned long data0;
	unsigned long data1;
	int updown;
#ifdef CONFIG_ANDROID
	int x,y;
#endif /* CONFIG_ANDROID */

	data0 = readl(ts_base+S3C_ADCDAT0);
	data1 = readl(ts_base+S3C_ADCDAT1);

	updown = (!(data0 & S3C_ADCDAT0_UPDOWN)) && (!(data1 & S3C_ADCDAT1_UPDOWN));

	if (updown) {
		if (ts->count) {

#ifdef CONFIG_TOUCHSCREEN_S3C_DEBUG
			{
				struct timeval tv;
				do_gettimeofday(&tv);
				printk(KERN_INFO "T: %06d, X: %03ld, Y: %03ld\n", (int)tv.tv_usec, ts->xp, ts->yp);
			}
#endif

#ifdef CONFIG_ANDROID
			x=(int) ts->xp/ts->count;
			y=(int) ts->yp/ts->count;
#if defined(CONFIG_FB_S3C_LTE480WV) || defined(CONFIG_FB_S3C_UTLCD7B) 
			y = 4000 - y;
#endif /* CONFIG_FB_S3C_LTE480WV */
			input_report_abs(ts->dev, ABS_X, x);
			input_report_abs(ts->dev, ABS_Y, y);
			input_report_abs(ts->dev, ABS_Z, 0);
			input_report_key(ts->dev, BTN_TOUCH, 1);
			input_sync(ts->dev);
#else /* CONFIG_ANDROID */
			input_report_abs(ts->dev, ABS_X, ts->xp);
			input_report_abs(ts->dev, ABS_Y, ts->yp);

			input_report_key(ts->dev, BTN_TOUCH, 1);
			input_report_abs(ts->dev, ABS_PRESSURE, 1);
			input_sync(ts->dev);
#endif /* CONFIG_ANDROID */
		}

		ts->xp = 0;
		ts->yp = 0;
		ts->count = 0;

		writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts_base+S3C_ADCTSC);
		writel(readl(ts_base+S3C_ADCCON) | S3C_ADCCON_ENABLE_START, ts_base+S3C_ADCCON);
	} else {
		ts->count = 0;
#ifdef CONFIG_ANDROID
		input_report_abs(ts->dev, ABS_X, ts->xp);
		input_report_abs(ts->dev, ABS_Y, ts->yp);
		input_report_abs(ts->dev, ABS_Z, 0);
#endif /* CONFIG_ANDROID */
		input_report_key(ts->dev, BTN_TOUCH, 0);
#ifndef CONFIG_ANDROID
		input_report_abs(ts->dev, ABS_PRESSURE, 0);
#endif /* !CONFIG_ANDROID */
		input_sync(ts->dev);

		writel(WAIT4INT(0), ts_base+S3C_ADCTSC);
	}
}
Exemplo n.º 17
0
/*
 * The functions for inserting/removing us as a module.
 */
static int __init s3c_ts_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct device *dev;
	struct input_dev *input_dev;
	struct s3c_ts_mach_info *s3c_ts_cfg;
	int ret, size;
	int irq_flags = 0;

	dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(dev, "no memory resource specified\n");
		return -ENOENT;
	}

	size = (res->end - res->start) + 1;
	ts_mem = request_mem_region(res->start, size, pdev->name);
	if (ts_mem == NULL) {
		dev_err(dev, "failed to get memory region\n");
		ret = -ENOENT;
		goto err_req;
	}

	ts_base = ioremap(res->start, size);
	if (ts_base == NULL) {
		dev_err(dev, "failed to ioremap() region\n");
		ret = -EINVAL;
		goto err_map;
	}

	ts_clock = clk_get(&pdev->dev, "adc");
	if (IS_ERR(ts_clock)) {
		dev_err(dev, "failed to find watchdog clock source\n");
		ret = PTR_ERR(ts_clock);
		goto err_clk;
	}

	clk_enable(ts_clock);

	s3c_ts_cfg = s3c_ts_get_platdata(&pdev->dev);
	if ((s3c_ts_cfg->presc&0xff) > 0)
		writel(S3C_ADCCON_PRSCEN | S3C_ADCCON_PRSCVL(s3c_ts_cfg->presc&0xFF),\
				ts_base+S3C_ADCCON);
	else
		writel(0, ts_base+S3C_ADCCON);

	/* Initialise registers */
	if ((s3c_ts_cfg->delay&0xffff) > 0)
		writel(s3c_ts_cfg->delay & 0xffff, ts_base+S3C_ADCDLY);

	if (s3c_ts_cfg->resol_bit == 12) {
		switch (s3c_ts_cfg->s3c_adc_con) {
		case ADC_TYPE_2:
			writel(readl(ts_base+S3C_ADCCON)|S3C_ADCCON_RESSEL_12BIT, ts_base+S3C_ADCCON);
			break;

		case ADC_TYPE_1:
			writel(readl(ts_base+S3C_ADCCON)|S3C_ADCCON_RESSEL_12BIT_1, ts_base+S3C_ADCCON);
			break;

		default:
			dev_err(dev, "Touchscreen over this type of AP isn't supported !\n");
			break;
		}
	}

	writel(WAIT4INT(0), ts_base+S3C_ADCTSC);

	ts = kzalloc(sizeof(struct s3c_ts_info), GFP_KERNEL);

	input_dev = input_allocate_device();
	if (!input_dev) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	ts->dev = input_dev;

	ts->dev->evbit[0] = 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);

	if (s3c_ts_cfg->resol_bit==12) {
#ifdef CONFIG_ANDROID
#ifndef CONFIG_CPU_S5PV210_EVT1
		input_set_abs_params(ts->dev, ABS_X, 0, 800, 0, 0);
		input_set_abs_params(ts->dev, ABS_Y, 0, 480, 0, 0);
		//  input_set_abs_params(ts->dev, ABS_Z, 0, 0, 0, 0);

		set_bit(0,ts->dev->evbit);
		set_bit(1,ts->dev->evbit);
		set_bit(2,ts->dev->evbit);
		set_bit(3,ts->dev->evbit);
		set_bit(5,ts->dev->evbit);

		set_bit(0,ts->dev->relbit);
		set_bit(1,ts->dev->relbit);

		set_bit(0,ts->dev->absbit);
		set_bit(1,ts->dev->absbit);
		set_bit(2,ts->dev->absbit);

		set_bit(0,ts->dev->swbit);

		for (err=0; err < 512; err++)
			set_bit(err,ts->dev->keybit);

		input_event(ts->dev,5,0,1);
#else /* !CONFIG_CPU_S5PV210_EVT1 */
		input_set_abs_params(ts->dev, ABS_X, X_COOR_MIN, X_COOR_MAX, X_COOR_FUZZ, 0);
		input_set_abs_params(ts->dev, ABS_Y, Y_COOR_MIN, Y_COOR_MAX, Y_COOR_FUZZ, 0);
#endif /* !CONFIG_CPU_S5PV210_EVT1 */
#else /* CONFIG_ANDROID */
		input_set_abs_params(ts->dev, ABS_X, 0, 0xFFF, 0, 0);
		input_set_abs_params(ts->dev, ABS_Y, 0, 0xFFF, 0, 0);
#endif /* CONFIG_ANDROID */
	} else {
		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);

	sprintf(ts->phys, "input(ts)");

	ts->dev->name = s3c_ts_name;
	ts->dev->phys = ts->phys;
	ts->dev->id.bustype = BUS_RS232;
	ts->dev->id.vendor = 0xDEAD;
	ts->dev->id.product = 0xBEEF;
	ts->dev->id.version = S3C_TSVERSION;

	ts->shift = s3c_ts_cfg->oversampling_shift;
	ts->resol_bit = s3c_ts_cfg->resol_bit;
	ts->s3c_adc_con = s3c_ts_cfg->s3c_adc_con;

#ifdef CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	ts->early_suspend.suspend = ts_early_suspend;
	ts->early_suspend.resume =ts_late_resume;
	register_early_suspend(&ts->early_suspend);
#endif /* CONFIG_HAS_EARLYSUSPEND */

	/* For IRQ_PENDUP */
	ts_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (ts_irq == NULL) {
		dev_err(dev, "no irq resource specified\n");
		ret = -ENOENT;
		goto err_irq;
	}

	ret = request_irq(ts_irq->start, stylus_updown, irq_flags, "s3c_updown", ts);
	if (ret != 0) {
		dev_err(dev, "s3c_ts.c: Could not allocate ts IRQ_PENDN !\n");
		ret = -EIO;
		goto err_irq;
	}

	/* For IRQ_ADC */
	ts_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	if (ts_irq == NULL) {
		dev_err(dev, "no irq resource specified\n");
		ret = -ENOENT;
		goto err_irq;
	}

	ret = request_irq(ts_irq->start, stylus_action, irq_flags, "s3c_action", ts);
	if (ret != 0) {
		dev_err(dev, "s3c_ts.c: Could not allocate ts IRQ_ADC !\n");
		ret =  -EIO;
		goto err_irq;
	}

	printk(KERN_INFO "%s got loaded successfully : %d bits\n", s3c_ts_name, s3c_ts_cfg->resol_bit);

	/* All went ok, so register to the input system */
	ret = input_register_device(ts->dev);
	if (ret) {
		dev_err(dev, "s3c_ts.c: Could not register input device(touchscreen)!\n");
		ret = -EIO;
		goto fail;
	}

	return 0;

fail:
	free_irq(ts_irq->start, ts->dev);
	free_irq(ts_irq->end, ts->dev);

err_irq:
	input_free_device(input_dev);
	kfree(ts);

err_alloc:
	clk_disable(ts_clock);
	clk_put(ts_clock);

err_clk:
	iounmap(ts_base);

err_map:
	release_resource(ts_mem);
	kfree(ts_mem);

err_req:
	return ret;
}