/*\r
* TI TWL4030 for beagle board\r
+ * register implementation based on TPS65950 ES1.0 specification\r
*\r
* Copyright (C) 2008 yajin<yajin@vm-kernel.org>\r
*\r
#include "cpu-all.h"\r
\r
#define VERBOSE 1\r
+#define TRACEW(regname, value) fprintf(stderr, "%s: %s = 0x%02x\n", __FUNCTION__, regname, value);\r
\r
//extern CPUState *cpu_single_env;\r
\r
\r
struct twl4030_s {\r
struct twl4030_i2c_s *i2c[5];\r
+ \r
+ int key_cfg;\r
+ int key_tst;\r
+ \r
+ uint8_t seq_mem[64][4]; /* power-management sequencing memory */\r
+};\r
+\r
+static const uint8_t addr_48_reset_values[256] = {\r
+ 0x51, 0x04, 0x02, 0xc0, 0x41, 0x41, 0x41, 0x10, /* 0x00...0x07 */\r
+ 0x10, 0x10, 0x06, 0x06, 0x06, 0x1f, 0x1f, 0x1f, /* 0x08...0x0f */\r
+ 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10...0x17 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, /* 0x18...0x1f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0a, 0x03, /* 0x20...0x27 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28...0x2f */\r
+ 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, /* 0x30...0x37 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38...0x3f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40...0x47 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48...0x4f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50...0x57 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58...0x5f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60...0x67 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68...0x6f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70...0x77 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78...0x7f */\r
+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, /* 0x80...0x87 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88...0x8f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90...0x97 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98...0x9f */\r
+ 0x00, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0xa0...0xa7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8...0xaf */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0...0xb7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8...0xb8 */\r
+ 0xa0, 0xa0, 0x64, 0x7f, 0x6c, 0x75, 0x64, 0x20, /* 0xc0...0xc7 */\r
+ 0x01, 0x17, 0x01, 0x02, 0x00, 0x36, 0x44, 0x07, /* 0xc8...0xcf */\r
+ 0x3b, 0x17, 0x6b, 0x04, 0x00, 0x00, 0x00, 0x00, /* 0xd0...0xd7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8...0xdf */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0...0xe7 */\r
+ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /* 0xe8...0xef */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0...0xf7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 /* 0xf8...0xff */\r
};\r
\r
+static const uint8_t addr_49_reset_values[256] = {\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00...0x07 */\r
+ 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, /* 0x08...0x0f */\r
+ 0x3f, 0x3f, 0x3f, 0x3f, 0x25, 0x00, 0x00, 0x00, /* 0x10...0x17 */\r
+ 0x00, 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x55, /* 0x18...0x1f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20...0x27 */\r
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, /* 0x28...0x2f */\r
+ 0x13, 0x00, 0x00, 0x00, 0x00, 0x79, 0x11, 0x00, /* 0x30...0x37 */\r
+ 0x00, 0x00, 0x06, 0x00, 0x44, 0x69, 0x00, 0x00, /* 0x38...0x3f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, /* 0x40...0x47 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48...0x4f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50...0x57 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58...0x5f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60...0x67 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68...0x6f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70...0x77 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78...0x7f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80...0x87 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88...0x8f */\r
+ 0x00, 0x90, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, /* 0x90...0x97 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98...0x9f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0...0xa7 */\r
+ 0x00, 0x00, 0x04, 0x00, 0x55, 0x01, 0x55, 0x05, /* 0xa8...0xaf */\r
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, /* 0xb0...0xb7 */\r
+ 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, /* 0xb8...0xbf */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 0xc0...0xc7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8...0xcf */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0...0xd7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8...0xdf */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0...0xe7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8...0xef */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0...0xf7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8...0xff */\r
+};\r
+\r
+static const uint8_t addr_4a_reset_values[256] = {\r
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00...0x07 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08...0x0f */\r
+ 0xc0, 0x8c, 0xde, 0xde, 0x00, 0x00, 0x00, 0x00, /* 0x10...0x17 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18...0x1f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20...0x27 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28...0x2f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30...0x37 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38...0x3f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40...0x47 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48...0x4f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50...0x57 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58...0x5f */\r
+ 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x55, 0x07, /* 0x60...0x67 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68...0x6f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70...0x77 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78...0x7f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, /* 0x80...0x87 */\r
+ 0x00, 0x68, 0x9b, 0x86, 0x48, 0x2a, 0x07, 0x28, /* 0x88...0x8f */\r
+ 0x09, 0x69, 0x90, 0x00, 0x2a, 0x00, 0x02, 0x00, /* 0x90...0x97 */\r
+ 0x10, 0xcd, 0x02, 0x68, 0x03, 0x00, 0x00, 0x00, /* 0x98...0x9f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0...0xa7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8...0xaf */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0...0xb7 */\r
+ 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, /* 0xb8...0xbf */\r
+ 0x0f, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x01, 0x00, /* 0xc0...0xc7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8...0xcf */\r
+ 0x00, 0x00, 0x03, 0x00, 0x00, 0xe0, 0x00, 0x00, /* 0xd0...0xd7 */\r
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8...0xdf */\r
+ 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, /* 0xe0...0xe7 */\r
+ 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8...0xef */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0...0xf7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0xf8...0xff */\r
+};\r
+\r
+static const uint8_t addr_4b_reset_values[256] = {\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00...0x07 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08...0x0f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10...0x17 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x18...0x1f */\r
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, /* 0x20...0x27 */\r
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28...0x2f */\r
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0xbf, 0xbf, /* 0x30...0x37 */\r
+ 0xbf, 0xab, 0x00, 0x08, 0x3f, 0x15, 0x40, 0x0e, /* 0x38...0x3f */\r
+ 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40...0x47 */\r
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, /* 0x48...0x4f */\r
+ 0x00, 0x02, 0x00, 0x04, 0x0d, 0x00, 0x00, 0x00, /* 0x50...0x57 */\r
+ 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58...0x5f */\r
+ 0x00, 0x00, 0x2f, 0x18, 0x0f, 0x08, 0x0f, 0x08, /* 0x60...0x67 */\r
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68...0x6f */\r
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x80, 0x03, /* 0x70...0x77 */\r
+ 0x08, 0x09, 0x00, 0x00, 0x08, 0x03, 0x80, 0x03, /* 0x78...0x7f */\r
+ 0x08, 0x02, 0x00, 0x00, 0x08, 0x00, 0x80, 0x03, /* 0x80...0x87 */\r
+ 0x08, 0x08, 0x20, 0x00, 0x00, 0x02, 0x80, 0x04, /* 0x88...0x8f */\r
+ 0x08, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, /* 0x90...0x97 */\r
+ 0x08, 0x02, 0xe0, 0x01, 0x08, 0x00, 0xe0, 0x00, /* 0x98...0x9f */\r
+ 0x08, 0x01, 0xe0, 0x01, 0x08, 0x04, 0xe0, 0x03, /* 0xa0...0xa7 */\r
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8...0xaf */\r
+ 0x20, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0...0xb7 */\r
+ 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, /* 0xb8...0xbf */\r
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, /* 0xc0...0xc7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, /* 0xc8...0xcf */\r
+ 0x00, 0x08, 0xe0, 0x00, 0x08, 0x00, 0x00, 0x00, /* 0xd0...0xd7 */\r
+ 0x14, 0x08, 0xe0, 0x02, 0x08, 0xe0, 0x00, 0x08, /* 0xd8...0xdf */\r
+ 0xe0, 0x05, 0x08, 0xe0, 0x06, 0x08, 0xe0, 0x00, /* 0xe0...0xe7 */\r
+ 0x08, 0xe0, 0x00, 0x08, 0xe0, 0x06, 0x06, 0xe0, /* 0xe8...0xef */\r
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0...0xf7 */\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0xf8...0xff */\r
+};\r
\r
static uint8_t twl4030_48_read(void *opaque, uint8_t addr)\r
{\r
- //struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
- //int reg = 0;\r
- \r
- printf("twl4030_48_read addr %x\n",addr);\r
+ struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
\r
- switch (addr)\r
- {\r
+ switch (addr) {\r
+ case 0xfd: /* PHY_PWR_CTRL */\r
+ return s->reg_data[addr];\r
default:\r
#ifdef VERBOSE\r
printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
static void twl4030_48_write(void *opaque, uint8_t addr, uint8_t value)\r
{\r
//struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
- //int line;\r
- //int reg = 0;\r
- //struct tm tm;\r
\r
- printf("twl4030_48_write addr %x value %x \n",addr,value);\r
- \r
- switch (addr)\r
- {\r
+ switch (addr) {\r
default:\r
#ifdef VERBOSE\r
printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
s->reg = data;\r
s->firstbyte = 0;\r
} else\r
- twl4030_48_write(s, s->reg ++, data);\r
+ twl4030_48_write(s, s->reg++, data);\r
\r
return 0;\r
}\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
\r
- return twl4030_48_read(s, s->reg ++);\r
+ return twl4030_48_read(s, s->reg++);\r
}\r
\r
static void twl4030_48_reset(i2c_slave *i2c)\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
s->reg = 0x00;\r
+ memcpy(s->reg_data, addr_48_reset_values, 256);\r
}\r
\r
static void twl4030_48_event(i2c_slave *i2c, enum i2c_event event)\r
\r
static uint8_t twl4030_49_read(void *opaque, uint8_t addr)\r
{\r
- //struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
- //int reg = 0;\r
- \r
- printf("twl4030_49_read addr %x\n",addr);\r
- \r
- switch (addr)\r
- {\r
+ struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+\r
+ switch (addr) {\r
+ case 0x9b: /* GPIO_DATADIR1 */\r
+ case 0xb1: /* GPIO_ISR1A */\r
+ case 0xb2: /* GPIO_ISR2A */\r
+ case 0xb3: /* GPIO_ISR3A */\r
+ return s->reg_data[addr];\r
default:\r
#ifdef VERBOSE\r
- printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
- //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+ fprintf(stderr, "%s: unknown register %02x pc %x\n",\r
+ __FUNCTION__, addr,cpu_single_env->regs[15]);\r
#endif\r
exit(-1);\r
- break;\r
}\r
}\r
\r
static void twl4030_49_write(void *opaque, uint8_t addr, uint8_t value)\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
- //int line;\r
- //int reg = 0;\r
- //struct tm tm;\r
- \r
- //printf("twl4030_49_write addr %x value %x \n", addr, value);\r
\r
- switch (addr)\r
- {\r
- case 0xaa:\r
- case 0xab:\r
- case 0xac:\r
- case 0xad:\r
- case 0xae:\r
- case 0xaf:\r
- fprintf(stderr,"%s: addr %x value %02x\n", __FUNCTION__, addr, value);\r
- /* fallthrough */\r
- case 0xb4: /*GPIO IMR*/\r
- case 0xb5:\r
- case 0xb6:\r
- case 0xb7:\r
- case 0xb8:\r
- case 0xb9:\r
- case 0xba:\r
- case 0xbb:\r
- case 0xbc:\r
- case 0xc5:\r
- s->reg_data[addr] = value;\r
- break;\r
- \r
+ switch (addr) {\r
+ case 0xaa: /* GPIO_CTRL */\r
+ case 0xab: /* GPIOPUPDCTR1 */\r
+ case 0xac: /* GPIOPUPDCTR2 */\r
+ case 0xad: /* GPIOPUPDCTR3 */\r
+ case 0xae: /* GPIOPUPDCTR4 */\r
+ s->reg_data[addr] = value;\r
+ break;\r
+ case 0xaf: /* GPIOPUPDCTR5 */\r
+ s->reg_data[addr] = value & 0x0f;\r
+ break;\r
+ case 0xb4: /* GPIO_IMR1A */\r
+ case 0xb5: /* GPIO_IMR2A */\r
+ s->reg_data[addr] = value;\r
+ break;\r
+ case 0xb6: /* GPIO_IMR3A */\r
+ s->reg_data[addr] = value & 0x03;\r
+ break;\r
+ case 0xc5: /* GPIO_SIH_CTRL */\r
+ s->reg_data[addr] = value & 0x07;\r
+ break;\r
default:\r
#ifdef VERBOSE\r
printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,\r
s->reg = data;\r
s->firstbyte = 0;\r
} else\r
- twl4030_49_write(s, s->reg ++, data);\r
+ twl4030_49_write(s, s->reg++, data);\r
\r
return 0;\r
}\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
\r
- return twl4030_49_read(s, s->reg ++);\r
+ return twl4030_49_read(s, s->reg++);\r
}\r
\r
static void twl4030_49_reset(i2c_slave *i2c)\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
s->reg = 0x00;\r
+ memcpy(s->reg_data, addr_49_reset_values, 256);\r
}\r
\r
static void twl4030_49_event(i2c_slave *i2c, enum i2c_event event)\r
\r
static uint8_t twl4030_4a_read(void *opaque, uint8_t addr)\r
{\r
- //struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
- //int reg = 0;\r
- \r
- printf("twl4030_4a_read addr %x\n",addr);\r
+ struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
\r
- switch (addr)\r
- {\r
+ switch (addr) {\r
+ case 0x61: /* MADC_ISR1 */\r
+ case 0xb9: /* BCIISR1A */\r
+ case 0xba: /* BCIISR2A */\r
+ case 0xe3: /* KEYP_ISR1 */\r
+ case 0xee: /* LEDEN */\r
+ return s->reg_data[addr];\r
default:\r
#ifdef VERBOSE\r
printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
//int reg = 0;\r
//struct tm tm;\r
\r
- fprintf(stderr, "%s: addr %x value %02x\n", __FUNCTION__, addr, value);\r
- \r
- switch (addr)\r
- {\r
- case 0xee: /*LED EN*/\r
- case 0xe4:\r
- case 0xe9:\r
- case 0xbb:\r
- case 0xbc:\r
- case 0x62:\r
- \r
- case 0x61:\r
- case 0xb9:\r
- case 0xba:\r
- case 0xef:\r
- case 0xf0:\r
+ switch (addr) {\r
+ case 0x61: /* MADC_ISR1 */\r
+ s->reg_data[value] &= ~(value & 0x0f);\r
+ break;\r
+ case 0x62: /* MADC_IMR1 */\r
+ s->reg_data[value] = value & 0x0f;\r
+ break;\r
+ case 0xb9: /* BCIISR1A */\r
+ s->reg_data[value] &= ~value;\r
+ break;\r
+ case 0xba: /* BCIISR2A */\r
+ s->reg_data[value] &= ~(value & 0x0f);\r
+ break;\r
+ case 0xbb: /* BCIIMR1A */\r
+ s->reg_data[addr] = value;\r
+ break;\r
+ case 0xbc: /* BCIIMR2A */\r
+ s->reg_data[addr] = value & 0x0f;\r
+ break;\r
+ case 0xe4: /* KEYP_IMR1 */\r
+ s->reg_data[addr] = value & 0x0f;\r
+ break;\r
+ case 0xe9: /* KEYP_SIH_CTRL */\r
+ s->reg_data[addr] = value & 0x07;\r
+ break;\r
+ case 0xee: /* LEDEN */\r
+ s->reg_data[addr] = value;\r
+#ifdef VERBOSE\r
+ fprintf(stderr, "%s: LEDA power=%s/enable=%s, LEDB power=%s/enable=%s\n", __FUNCTION__,\r
+ value & 0x10 ? "on" : "off", value & 0x01 ? "yes" : "no",\r
+ value & 0x20 ? "on" : "off", value & 0x02 ? "yes" : "no");\r
+#endif \r
+ break;\r
+ case 0xef: /* PWMAON */\r
s->reg_data[addr] = value;\r
break;\r
+ case 0xf0: /* PWMAOFF */\r
+ s->reg_data[addr] = value & 0x7f;\r
+ break;\r
default:\r
#ifdef VERBOSE\r
printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
s->reg = data;\r
s->firstbyte = 0;\r
} else\r
- twl4030_4a_write(s, s->reg ++, data);\r
+ twl4030_4a_write(s, s->reg++, data);\r
\r
return 0;\r
}\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
\r
- return twl4030_4a_read(s, s->reg ++);\r
+ return twl4030_4a_read(s, s->reg++);\r
}\r
\r
static void twl4030_4a_reset(i2c_slave *i2c)\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
s->reg = 0x00;\r
+ memcpy(s->reg_data, addr_4a_reset_values, 256);\r
}\r
\r
static void twl4030_4a_event(i2c_slave *i2c, enum i2c_event event)\r
\r
static uint8_t twl4030_4b_read(void *opaque, uint8_t addr)\r
{\r
- //struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
- //int reg = 0;\r
- \r
- printf("twl4030_4b_read addr %x\n",addr);\r
+ struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
\r
- switch (addr)\r
- {\r
+ switch (addr) {\r
+ case 0x2e: /* PWR_ISR1 */\r
+ case 0x33: /* PWR_EDR1 */\r
+ case 0x34: /* PWR_EDR2 */\r
+ case 0x45: /* STS_HW_CONDITIONS */\r
+ return s->reg_data[addr];\r
default:\r
#ifdef VERBOSE\r
printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
}\r
}\r
\r
+\r
static void twl4030_4b_write(void *opaque, uint8_t addr, uint8_t value)\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+ uint8_t seq_addr, seq_sub;\r
\r
- fprintf(stderr, "%s: addr %x value %02x\n", __FUNCTION__, addr, value);\r
- \r
- switch (addr)\r
- {\r
- case 0x2f:\r
- case 0x35:\r
- case 0x3b:\r
- case 0x44:\r
- case 0x82:\r
- case 0x85:\r
- case 0x7a:\r
- case 0x7d:\r
- case 0x8e:\r
- case 0x91:\r
- case 0x96:\r
- case 0x99:\r
-\r
- case 0x46:\r
- case 0x47:\r
- case 0x48:\r
- case 0x55:\r
- case 0x56:\r
- case 0x57:\r
- case 0x59:\r
- case 0x5a:\r
- case 0xcc:\r
- case 0xcd:\r
- case 0xcf:\r
- case 0xd0:\r
- case 0xd2:\r
- case 0xd3:\r
- case 0xd8:\r
- case 0xd9:\r
- case 0xe6:\r
+ switch (addr) {\r
+ case 0x46: /* P1_SW_EVENTS */\r
+ case 0x47: /* P2_SW_EVENTS */\r
+ case 0x48: /* P3_SW_EVENTS */\r
+ s->reg_data[addr] = value & 0x78;\r
+ break;\r
+ case 0x52: /* SEQ_ADD_W2P */\r
+ case 0x53: /* SEQ_ADD_P2A */\r
+ case 0x54: /* SEQ_ADD_A2W */\r
+ case 0x55: /* SEQ_ADD_A2S */\r
+ case 0x56: /* SEQ_ADD_S2A12 */\r
+ case 0x57: /* SEQ_ADD_S2A3 */\r
+ case 0x58: /* SEQ_ADD_WARM */\r
+ if (s->twl4030->key_cfg)\r
+ s->reg_data[addr] = value & 0x3f;\r
+ break;\r
+ case 0x59: /* MEMORY_ADDRESS */\r
+ if (s->twl4030->key_cfg)\r
+ s->reg_data[addr] = value;\r
+ break;\r
+ case 0x5a: /* MEMORY_DATA */\r
+ if (s->twl4030->key_cfg) {\r
+ s->reg_data[addr] = value;\r
+ seq_addr = s->reg_data[0x59];\r
+ seq_sub = seq_addr & 3;\r
+ seq_addr >>= 2;\r
+ if ((seq_addr >= 0x2b && seq_addr <= 0x3e) || (seq_addr <= 0x0e && seq_sub == 3))\r
+ s->twl4030->seq_mem[seq_addr][seq_sub] = value;\r
+ }\r
+ s->reg_data[0x59]++; /* TODO: check if autoincrement is write-protected as well */\r
+ break;\r
+ case 0x7a: /* VAUX3_DEV_GRP */\r
+ case 0x82: /* VMMC1_DEV_GRP */\r
+ case 0x8e: /* VPLL2_DEV_GRP */\r
+ case 0x96: /* VDAC_DEV_GRP */\r
+ case 0xcc: /* VUSB1V5_DEV_GRP */\r
+ case 0xcf: /* VUSB1V8_DEV_GRP */\r
+ case 0xd2: /* VUSB3V1_DEV_GRP */\r
+ case 0xe6: /* HFCLKOUT_DEV_GRP */\r
+ s->reg_data[addr] = (s->reg_data[addr] & 0x0f) | (value & 0xf0); \r
+ break;\r
+ case 0x2f: /* PWR_IMR1 */\r
+ s->reg_data[addr] = value;\r
+ break;\r
+ case 0x35: /* PWR_SIH_CTRL */\r
+ s->reg_data[addr] = value & 0x07;\r
+ break;\r
+ case 0x3b: /* CFG_BOOT */\r
+ if (s->twl4030->key_cfg)\r
+ s->reg_data[addr] = (s->reg_data[addr] & 0x70) | (value & 0x8f);\r
+ break;\r
+ case 0x44: /* PROTECT_KEY */\r
+ s->twl4030->key_cfg = 0;\r
+ s->twl4030->key_tst = 0;\r
+ switch (value) {\r
+ case 0x0C: \r
+ if (s->reg_data[addr] == 0xC0)\r
+ s->twl4030->key_cfg = 1;\r
+ break;\r
+ case 0xE0:\r
+ if (s->reg_data[addr] == 0x0E)\r
+ s->twl4030->key_tst = 1;\r
+ break;\r
+ case 0xEC:\r
+ if (s->reg_data[addr] == 0xCE) {\r
+ s->twl4030->key_cfg = 1;\r
+ s->twl4030->key_tst = 1;\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
s->reg_data[addr] = value;\r
break;\r
+ case 0x7d: /* VAUX3_DEDICATED */\r
+ if (s->twl4030->key_tst)\r
+ s->reg_data[addr] = value & 0x77;\r
+ else\r
+ s->reg_data[addr] = (s->reg_data[addr] & 0x70) | (value & 0x07);\r
+ break;\r
+ case 0x85: /* VMMC1_DEDICATED */\r
+ case 0x99: /* VDAC_DEDICATED */\r
+ if (s->twl4030->key_tst) \r
+ s->reg_data[addr] = value & 0x73;\r
+ else\r
+ s->reg_data[addr] = (s->reg_data[addr] & 0x70) | (value & 0x03);\r
+ break;\r
+ case 0x91: /* VPLL2_DEDICATED */\r
+ if (s->twl4030->key_tst)\r
+ s->reg_data[addr] = value & 0x7f;\r
+ else\r
+ s->reg_data[addr] = (s->reg_data[addr] & 0x70) | (value & 0x0f);\r
+ break;\r
+ case 0xcd: /* VUSB1V5_TYPE */\r
+ case 0xd0: /* VUSB1V8_TYPE */\r
+ case 0xd3: /* VUSB3V1_TYPE */\r
+ s->reg_data[addr] = value & 0x1f;\r
+ break;\r
+ case 0xd8: /* VUSB_DEDICATED1 */\r
+ s->reg_data[addr] = value & 0x1f;\r
+ break;\r
+ case 0xd9: /* VUSB_DEDICATED2 */\r
+ s->reg_data[addr] = value & 0x08;\r
+ break;\r
+ \r
default:\r
#ifdef VERBOSE\r
- printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
- //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+ fprintf(stderr, "%s: unknown register %02x value %0x pc %x \n", __FUNCTION__, \r
+ addr, value, cpu_single_env->regs[15]);\r
#endif\r
exit(-1);\r
break;\r
s->reg = data;\r
s->firstbyte = 0;\r
} else\r
- twl4030_4b_write(s, s->reg ++, data);\r
+ twl4030_4b_write(s, s->reg++, data);\r
\r
return 1;\r
}\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
\r
- return twl4030_4b_read(s, s->reg ++);\r
+ return twl4030_4b_read(s, s->reg++);\r
}\r
\r
static void twl4030_4b_reset(i2c_slave *i2c)\r
{\r
struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
s->reg = 0x00;\r
+ memcpy(s->reg_data, addr_4b_reset_values, 256);\r
+ s->twl4030->key_cfg = 0;\r
+ s->twl4030->key_tst = 0;\r
}\r
\r
static void twl4030_4b_event(i2c_slave *i2c, enum i2c_event event)\r