summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/export/i2c-s5l8700.h32
-rw-r--r--firmware/target/arm/s5l8700/i2c-s5l8700.c136
3 files changed, 170 insertions, 0 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 6f23012b61..fb192cd7ae 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -358,6 +358,8 @@ target/arm/pnx0101/i2c-pnx0101.c
358target/arm/i2c-telechips.c 358target/arm/i2c-telechips.c
359#elif CONFIG_I2C == I2C_S3C2440 359#elif CONFIG_I2C == I2C_S3C2440
360/* no i2c driver yet */ 360/* no i2c driver yet */
361#elif CONFIG_I2C == I2C_S5L8700
362target/arm/s5l8700/i2c-s5l8700.c
361#endif 363#endif
362 364
363#if CONFIG_CPU == PNX0101 365#if CONFIG_CPU == PNX0101
diff --git a/firmware/export/i2c-s5l8700.h b/firmware/export/i2c-s5l8700.h
new file mode 100644
index 0000000000..e6ffcfae55
--- /dev/null
+++ b/firmware/export/i2c-s5l8700.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Bertrik Sikken
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef _I2C_S5l8700_H
23#define _I2C_S5l8700_H
24
25#include "config.h"
26
27void i2c_init(void);
28int i2c_write(unsigned char slave, int address, int len, const unsigned char *data);
29int i2c_read(unsigned char slave, int address, int len, unsigned char *data);
30
31#endif /* _I2C_S5l8700_H */
32
diff --git a/firmware/target/arm/s5l8700/i2c-s5l8700.c b/firmware/target/arm/s5l8700/i2c-s5l8700.c
new file mode 100644
index 0000000000..564bfdd4bd
--- /dev/null
+++ b/firmware/target/arm/s5l8700/i2c-s5l8700.c
@@ -0,0 +1,136 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Bertrik Sikken
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "system.h"
24#include "kernel.h"
25#include "i2c-s5l8700.h"
26
27/* Driver for the s5l8700 built-in I2C controller in master mode
28
29 Both the i2c_read and i2c_write function take the following arguments:
30 * slave, the address of the i2c slave device to read from / write to
31 * address, optional sub-address in the i2c slave (unused if -1)
32 * len, number of bytes to be transfered
33 * data, pointer to data to be transfered
34 A return value < 0 indicates an error.
35
36 Known issues:
37 * uses polled mode (not interrupt driven), just like the OF
38 * ACK from slave is not checked, so functions never return an error
39*/
40
41static struct mutex i2c_mtx;
42
43void i2c_init(void)
44{
45 mutex_init(&i2c_mtx);
46
47 /* enable I2C pins */
48 PCON10 = (2 << 2) |
49 (2 << 0);
50
51 /* enable I2C clock */
52 PWRCON &= ~(1 << 5);
53
54 /* initial config */
55 IICADD = 0;
56 IICCON = (1 << 7) | /* ACK_GEN */
57 (1 << 6) | /* CLKSEL = PCLK/512 */
58 (1 << 5) | /* INT_EN */
59 (1 << 4) | /* IRQ clear */
60 (3 << 0); /* CK_REG */
61
62 /* serial output on */
63 IICSTAT = (1 << 4);
64}
65
66int i2c_write(unsigned char slave, int address, int len, const unsigned char *data)
67{
68 mutex_lock(&i2c_mtx);
69
70 /* START */
71 IICDS = slave & ~1;
72 IICSTAT = 0xF0;
73 IICCON = 0xF3;
74 while ((IICCON & (1 << 4)) == 0);
75
76 if (address >= 0) {
77 /* write address */
78 IICDS = address;
79 IICCON = 0xF3;
80 while ((IICCON & (1 << 4)) == 0);
81 }
82
83 /* write data */
84 while (len--) {
85 IICDS = *data++;
86 IICCON = 0xF3;
87 while ((IICCON & (1 << 4)) == 0);
88 }
89
90 /* STOP */
91 IICSTAT = 0xD0;
92 IICCON = 0xF3;
93 while ((IICSTAT & (1 << 5)) != 0);
94
95 mutex_unlock(&i2c_mtx);
96 return 0;
97}
98
99int i2c_read(unsigned char slave, int address, int len, unsigned char *data)
100{
101 mutex_lock(&i2c_mtx);
102
103 if (address >= 0) {
104 /* START */
105 IICDS = slave & ~1;
106 IICSTAT = 0xF0;
107 IICCON = 0xF3;
108 while ((IICCON & (1 << 4)) == 0);
109
110 /* write address */
111 IICDS = address;
112 IICCON = 0xF3;
113 while ((IICCON & (1 << 4)) == 0);
114 }
115
116 /* (repeated) START */
117 IICDS = slave | 1;
118 IICSTAT = 0xB0;
119 IICCON = 0xF3;
120 while ((IICCON & (1 << 4)) == 0);
121
122 while (len--) {
123 IICCON = (len == 0) ? 0x73 : 0xF3; /* NACK or ACK */
124 while ((IICCON & (1 << 4)) == 0);
125 *data++ = IICDS;
126 }
127
128 /* STOP */
129 IICSTAT = 0x90;
130 IICCON = 0xF3;
131 while ((IICSTAT & (1 << 5)) != 0);
132
133 mutex_unlock(&i2c_mtx);
134 return 0;
135}
136