Get interrupt endpoints fully working on Ingenic Jz4740 targets
[kugel-rb.git] / firmware / drivers / tsc2100.c
blob271a557822e03827ad4a6bc9a623241b612537bf
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
10 * Copyright (C) 2007 by Jonathan Gordon
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "config.h"
23 #include "cpu.h"
24 #include "system.h"
25 #include "spi.h"
26 #include "tsc2100.h"
28 /* adc_data contains the last readings from the tsc2100 */
29 static short adc_data[10];
30 static short adc_status;
31 static long adc_last_read=0;
32 static long adc_last_touch_read=0;
33 static long adc_last_volt_read=0;
35 void tsc2100_read_data(void)
37 int page = 0, address = 0;
38 unsigned int i;
39 unsigned short command = 0x8000|(page << 11)|(address << 5);
40 unsigned char out[] = {command >> 8, command & 0xff};
41 unsigned char *p_adc_data=(unsigned char *)&adc_data;
43 adc_status|=tsc2100_readreg(TSSTAT_PAGE, TSSTAT_ADDRESS);
45 adc_last_read=current_tick;
47 spi_block_transfer(SPI_target_TSC2100, false,
48 out, sizeof(out), (char *)adc_data, sizeof(adc_data));
50 for(i=0; i<sizeof(adc_data); i+=2)
51 adc_data[i>>1]=(short)(p_adc_data[i]<<8|p_adc_data[i+1]);
54 /* Read X, Y, Z1, Z2 touchscreen coordinates. */
55 bool tsc2100_read_touch(short *x, short* y, short *z1, short *z2)
57 /* Note: This could cause problems if the current tick is not reset in ~1.3
58 * years. Noting this in the event that a suspend/resume function
59 * is added.
61 if( (adc_status&(3<<9)) && (adc_last_read - adc_last_touch_read>=0) ) {
62 *x = adc_data[0];
63 *y = adc_data[1];
64 *z1 = adc_data[2];
65 *z2 = adc_data[3];
67 adc_status&=~(3<<9);
69 adc_last_touch_read=current_tick;
71 return true;
72 } else {
73 return false;
77 bool tsc2100_read_volt(short *bat1, short *bat2, short *aux)
79 if( (adc_status&(7<<4)) && TIME_BEFORE(adc_last_volt_read, adc_last_read)) {
80 *bat1 = adc_data[5];
81 *bat2 = adc_data[6];
82 *aux = adc_data[7];
84 adc_status&=~(7<<4);
85 adc_last_volt_read=current_tick;
86 return true;
87 } else {
88 return false;
92 void tsc2100_set_mode(bool poweron, unsigned char scan_mode)
94 short tsadc=(scan_mode<<TSADC_ADSCM_SHIFT)| /* mode */
95 (0x3<<TSADC_RESOL_SHIFT)| /* 12 bit resolution */
96 (0x2<<TSADC_ADCR_SHIFT )| /* 2 MHz internal clock */
97 (0x2<<TSADC_PVSTC_SHIFT);
99 if(!poweron)
101 tsadc|=TSADC_ADST;
104 if(scan_mode<6)
105 tsadc|=TSADC_PSTCM;
107 tsc2100_writereg(TSADC_PAGE, TSADC_ADDRESS, tsadc);
110 void tsc2100_adc_init(void)
112 /* Set the TSC2100 to read touchscreen */
113 tsc2100_set_mode(true, 0x01);
115 tsc2100_writereg(TSSTAT_PAGE, TSSTAT_ADDRESS,
116 (0x1<<TSSTAT_PINTDAV_SHIFT) /* Data available only */
119 /* An additional 2 mA can be saved here by powering down vref between
120 * conversions, but it adds a click to the audio on the M:Robe 500
122 tsc2100_writereg(TSREF_PAGE, TSREF_ADDRESS,
123 TSREF_VREFM|TSREF_IREFV);
126 short tsc2100_readreg(int page, int address)
128 unsigned short command = 0x8000|(page << 11)|(address << 5);
129 unsigned char out[] = {command >> 8, command & 0xff};
130 unsigned char in[2];
131 spi_block_transfer(SPI_target_TSC2100, false,
132 out, sizeof(out), in, sizeof(in));
133 return (in[0]<<8)|in[1];
137 void tsc2100_writereg(int page, int address, short value)
139 unsigned short command = (page << 11)|(address << 5);
140 unsigned char out[4] = {command >> 8, command & 0xff,
141 value >> 8, value & 0xff};
142 spi_block_transfer(SPI_target_TSC2100, false,
143 out, sizeof(out), NULL, 0);
146 void tsc2100_keyclick(void)
148 // 1100 0100 0001 0000
149 //short val = 0xC410;
150 tsc2100_writereg(TSAC2_PAGE, TSAC2_ADDRESS, tsc2100_readreg(TSAC2_PAGE, TSAC2_ADDRESS)&0x8000);
153 #ifdef HAVE_HARDWARE_BEEP
155 void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
157 tsc2100_keyclick();
159 #endif