lm832x.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. /*
  2. * National Semiconductor LM8322/8323 GPIO keyboard & PWM chips.
  3. *
  4. * Copyright (C) 2008 Nokia Corporation
  5. * Written by Andrzej Zaborowski <andrew@openedhand.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 or
  10. * (at your option) version 3 of the License.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "hw.h"
  21. #include "i2c.h"
  22. #include "qemu/timer.h"
  23. #include "ui/console.h"
  24. typedef struct {
  25. I2CSlave i2c;
  26. uint8_t i2c_dir;
  27. uint8_t i2c_cycle;
  28. uint8_t reg;
  29. qemu_irq nirq;
  30. uint16_t model;
  31. struct {
  32. qemu_irq out[2];
  33. int in[2][2];
  34. } mux;
  35. uint8_t config;
  36. uint8_t status;
  37. uint8_t acttime;
  38. uint8_t error;
  39. uint8_t clock;
  40. struct {
  41. uint16_t pull;
  42. uint16_t mask;
  43. uint16_t dir;
  44. uint16_t level;
  45. qemu_irq out[16];
  46. } gpio;
  47. struct {
  48. uint8_t dbnctime;
  49. uint8_t size;
  50. uint8_t start;
  51. uint8_t len;
  52. uint8_t fifo[16];
  53. } kbd;
  54. struct {
  55. uint16_t file[256];
  56. uint8_t faddr;
  57. uint8_t addr[3];
  58. QEMUTimer *tm[3];
  59. } pwm;
  60. } LM823KbdState;
  61. #define INT_KEYPAD (1 << 0)
  62. #define INT_ERROR (1 << 3)
  63. #define INT_NOINIT (1 << 4)
  64. #define INT_PWMEND(n) (1 << (5 + n))
  65. #define ERR_BADPAR (1 << 0)
  66. #define ERR_CMDUNK (1 << 1)
  67. #define ERR_KEYOVR (1 << 2)
  68. #define ERR_FIFOOVR (1 << 6)
  69. static void lm_kbd_irq_update(LM823KbdState *s)
  70. {
  71. qemu_set_irq(s->nirq, !s->status);
  72. }
  73. static void lm_kbd_gpio_update(LM823KbdState *s)
  74. {
  75. }
  76. static void lm_kbd_reset(LM823KbdState *s)
  77. {
  78. s->config = 0x80;
  79. s->status = INT_NOINIT;
  80. s->acttime = 125;
  81. s->kbd.dbnctime = 3;
  82. s->kbd.size = 0x33;
  83. s->clock = 0x08;
  84. lm_kbd_irq_update(s);
  85. lm_kbd_gpio_update(s);
  86. }
  87. static void lm_kbd_error(LM823KbdState *s, int err)
  88. {
  89. s->error |= err;
  90. s->status |= INT_ERROR;
  91. lm_kbd_irq_update(s);
  92. }
  93. static void lm_kbd_pwm_tick(LM823KbdState *s, int line)
  94. {
  95. }
  96. static void lm_kbd_pwm_start(LM823KbdState *s, int line)
  97. {
  98. lm_kbd_pwm_tick(s, line);
  99. }
  100. static void lm_kbd_pwm0_tick(void *opaque)
  101. {
  102. lm_kbd_pwm_tick(opaque, 0);
  103. }
  104. static void lm_kbd_pwm1_tick(void *opaque)
  105. {
  106. lm_kbd_pwm_tick(opaque, 1);
  107. }
  108. static void lm_kbd_pwm2_tick(void *opaque)
  109. {
  110. lm_kbd_pwm_tick(opaque, 2);
  111. }
  112. enum {
  113. LM832x_CMD_READ_ID = 0x80, /* Read chip ID. */
  114. LM832x_CMD_WRITE_CFG = 0x81, /* Set configuration item. */
  115. LM832x_CMD_READ_INT = 0x82, /* Get interrupt status. */
  116. LM832x_CMD_RESET = 0x83, /* Reset, same as external one */
  117. LM823x_CMD_WRITE_PULL_DOWN = 0x84, /* Select GPIO pull-up/down. */
  118. LM832x_CMD_WRITE_PORT_SEL = 0x85, /* Select GPIO in/out. */
  119. LM832x_CMD_WRITE_PORT_STATE = 0x86, /* Set GPIO pull-up/down. */
  120. LM832x_CMD_READ_PORT_SEL = 0x87, /* Get GPIO in/out. */
  121. LM832x_CMD_READ_PORT_STATE = 0x88, /* Get GPIO pull-up/down. */
  122. LM832x_CMD_READ_FIFO = 0x89, /* Read byte from FIFO. */
  123. LM832x_CMD_RPT_READ_FIFO = 0x8a, /* Read FIFO (no increment). */
  124. LM832x_CMD_SET_ACTIVE = 0x8b, /* Set active time. */
  125. LM832x_CMD_READ_ERROR = 0x8c, /* Get error status. */
  126. LM832x_CMD_READ_ROTATOR = 0x8e, /* Read rotator status. */
  127. LM832x_CMD_SET_DEBOUNCE = 0x8f, /* Set debouncing time. */
  128. LM832x_CMD_SET_KEY_SIZE = 0x90, /* Set keypad size. */
  129. LM832x_CMD_READ_KEY_SIZE = 0x91, /* Get keypad size. */
  130. LM832x_CMD_READ_CFG = 0x92, /* Get configuration item. */
  131. LM832x_CMD_WRITE_CLOCK = 0x93, /* Set clock config. */
  132. LM832x_CMD_READ_CLOCK = 0x94, /* Get clock config. */
  133. LM832x_CMD_PWM_WRITE = 0x95, /* Write PWM script. */
  134. LM832x_CMD_PWM_START = 0x96, /* Start PWM engine. */
  135. LM832x_CMD_PWM_STOP = 0x97, /* Stop PWM engine. */
  136. LM832x_GENERAL_ERROR = 0xff, /* There was one error.
  137. Previously was represented by -1
  138. This is not a command */
  139. };
  140. #define LM832x_MAX_KPX 8
  141. #define LM832x_MAX_KPY 12
  142. static uint8_t lm_kbd_read(LM823KbdState *s, int reg, int byte)
  143. {
  144. int ret;
  145. switch (reg) {
  146. case LM832x_CMD_READ_ID:
  147. ret = 0x0400;
  148. break;
  149. case LM832x_CMD_READ_INT:
  150. ret = s->status;
  151. if (!(s->status & INT_NOINIT)) {
  152. s->status = 0;
  153. lm_kbd_irq_update(s);
  154. }
  155. break;
  156. case LM832x_CMD_READ_PORT_SEL:
  157. ret = s->gpio.dir;
  158. break;
  159. case LM832x_CMD_READ_PORT_STATE:
  160. ret = s->gpio.mask;
  161. break;
  162. case LM832x_CMD_READ_FIFO:
  163. if (s->kbd.len <= 1)
  164. return 0x00;
  165. /* Example response from the two commands after a INT_KEYPAD
  166. * interrupt caused by the key 0x3c being pressed:
  167. * RPT_READ_FIFO: 55 bc 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
  168. * READ_FIFO: bc 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
  169. * RPT_READ_FIFO: bc 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
  170. *
  171. * 55 is the code of the key release event serviced in the previous
  172. * interrupt handling.
  173. *
  174. * TODO: find out whether the FIFO is advanced a single character
  175. * before reading every byte or the whole size of the FIFO at the
  176. * last LM832x_CMD_READ_FIFO. This affects LM832x_CMD_RPT_READ_FIFO
  177. * output in cases where there are more than one event in the FIFO.
  178. * Assume 0xbc and 0x3c events are in the FIFO:
  179. * RPT_READ_FIFO: 55 bc 3c 00 4e ff 0a 50 08 00 29 d9 08 01 c9
  180. * READ_FIFO: bc 3c 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9
  181. * Does RPT_READ_FIFO now return 0xbc and 0x3c or only 0x3c?
  182. */
  183. s->kbd.start ++;
  184. s->kbd.start &= sizeof(s->kbd.fifo) - 1;
  185. s->kbd.len --;
  186. return s->kbd.fifo[s->kbd.start];
  187. case LM832x_CMD_RPT_READ_FIFO:
  188. if (byte >= s->kbd.len)
  189. return 0x00;
  190. return s->kbd.fifo[(s->kbd.start + byte) & (sizeof(s->kbd.fifo) - 1)];
  191. case LM832x_CMD_READ_ERROR:
  192. return s->error;
  193. case LM832x_CMD_READ_ROTATOR:
  194. return 0;
  195. case LM832x_CMD_READ_KEY_SIZE:
  196. return s->kbd.size;
  197. case LM832x_CMD_READ_CFG:
  198. return s->config & 0xf;
  199. case LM832x_CMD_READ_CLOCK:
  200. return (s->clock & 0xfc) | 2;
  201. default:
  202. lm_kbd_error(s, ERR_CMDUNK);
  203. fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
  204. return 0x00;
  205. }
  206. return ret >> (byte << 3);
  207. }
  208. static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
  209. {
  210. switch (reg) {
  211. case LM832x_CMD_WRITE_CFG:
  212. s->config = value;
  213. /* This must be done whenever s->mux.in is updated (never). */
  214. if ((s->config >> 1) & 1) /* MUX1EN */
  215. qemu_set_irq(s->mux.out[0], s->mux.in[0][(s->config >> 0) & 1]);
  216. if ((s->config >> 3) & 1) /* MUX2EN */
  217. qemu_set_irq(s->mux.out[0], s->mux.in[0][(s->config >> 2) & 1]);
  218. /* TODO: check that this is issued only following the chip reset
  219. * and not in the middle of operation and that it is followed by
  220. * the GPIO ports re-resablishing through WRITE_PORT_SEL and
  221. * WRITE_PORT_STATE (using a timer perhaps) and otherwise output
  222. * warnings. */
  223. s->status = 0;
  224. lm_kbd_irq_update(s);
  225. s->kbd.len = 0;
  226. s->kbd.start = 0;
  227. s->reg = LM832x_GENERAL_ERROR;
  228. break;
  229. case LM832x_CMD_RESET:
  230. if (value == 0xaa)
  231. lm_kbd_reset(s);
  232. else
  233. lm_kbd_error(s, ERR_BADPAR);
  234. s->reg = LM832x_GENERAL_ERROR;
  235. break;
  236. case LM823x_CMD_WRITE_PULL_DOWN:
  237. if (!byte)
  238. s->gpio.pull = value;
  239. else {
  240. s->gpio.pull |= value << 8;
  241. lm_kbd_gpio_update(s);
  242. s->reg = LM832x_GENERAL_ERROR;
  243. }
  244. break;
  245. case LM832x_CMD_WRITE_PORT_SEL:
  246. if (!byte)
  247. s->gpio.dir = value;
  248. else {
  249. s->gpio.dir |= value << 8;
  250. lm_kbd_gpio_update(s);
  251. s->reg = LM832x_GENERAL_ERROR;
  252. }
  253. break;
  254. case LM832x_CMD_WRITE_PORT_STATE:
  255. if (!byte)
  256. s->gpio.mask = value;
  257. else {
  258. s->gpio.mask |= value << 8;
  259. lm_kbd_gpio_update(s);
  260. s->reg = LM832x_GENERAL_ERROR;
  261. }
  262. break;
  263. case LM832x_CMD_SET_ACTIVE:
  264. s->acttime = value;
  265. s->reg = LM832x_GENERAL_ERROR;
  266. break;
  267. case LM832x_CMD_SET_DEBOUNCE:
  268. s->kbd.dbnctime = value;
  269. s->reg = LM832x_GENERAL_ERROR;
  270. if (!value)
  271. lm_kbd_error(s, ERR_BADPAR);
  272. break;
  273. case LM832x_CMD_SET_KEY_SIZE:
  274. s->kbd.size = value;
  275. s->reg = LM832x_GENERAL_ERROR;
  276. if (
  277. (value & 0xf) < 3 || (value & 0xf) > LM832x_MAX_KPY ||
  278. (value >> 4) < 3 || (value >> 4) > LM832x_MAX_KPX)
  279. lm_kbd_error(s, ERR_BADPAR);
  280. break;
  281. case LM832x_CMD_WRITE_CLOCK:
  282. s->clock = value;
  283. s->reg = LM832x_GENERAL_ERROR;
  284. if ((value & 3) && (value & 3) != 3) {
  285. lm_kbd_error(s, ERR_BADPAR);
  286. fprintf(stderr, "%s: invalid clock setting in RCPWM\n",
  287. __FUNCTION__);
  288. }
  289. /* TODO: Validate that the command is only issued once */
  290. break;
  291. case LM832x_CMD_PWM_WRITE:
  292. if (byte == 0) {
  293. if (!(value & 3) || (value >> 2) > 59) {
  294. lm_kbd_error(s, ERR_BADPAR);
  295. s->reg = LM832x_GENERAL_ERROR;
  296. break;
  297. }
  298. s->pwm.faddr = value;
  299. s->pwm.file[s->pwm.faddr] = 0;
  300. } else if (byte == 1) {
  301. s->pwm.file[s->pwm.faddr] |= value << 8;
  302. } else if (byte == 2) {
  303. s->pwm.file[s->pwm.faddr] |= value << 0;
  304. s->reg = LM832x_GENERAL_ERROR;
  305. }
  306. break;
  307. case LM832x_CMD_PWM_START:
  308. s->reg = LM832x_GENERAL_ERROR;
  309. if (!(value & 3) || (value >> 2) > 59) {
  310. lm_kbd_error(s, ERR_BADPAR);
  311. break;
  312. }
  313. s->pwm.addr[(value & 3) - 1] = value >> 2;
  314. lm_kbd_pwm_start(s, (value & 3) - 1);
  315. break;
  316. case LM832x_CMD_PWM_STOP:
  317. s->reg = LM832x_GENERAL_ERROR;
  318. if (!(value & 3)) {
  319. lm_kbd_error(s, ERR_BADPAR);
  320. break;
  321. }
  322. qemu_del_timer(s->pwm.tm[(value & 3) - 1]);
  323. break;
  324. case LM832x_GENERAL_ERROR:
  325. lm_kbd_error(s, ERR_BADPAR);
  326. break;
  327. default:
  328. lm_kbd_error(s, ERR_CMDUNK);
  329. fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
  330. break;
  331. }
  332. }
  333. static void lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
  334. {
  335. LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
  336. switch (event) {
  337. case I2C_START_RECV:
  338. case I2C_START_SEND:
  339. s->i2c_cycle = 0;
  340. s->i2c_dir = (event == I2C_START_SEND);
  341. break;
  342. default:
  343. break;
  344. }
  345. }
  346. static int lm_i2c_rx(I2CSlave *i2c)
  347. {
  348. LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
  349. return lm_kbd_read(s, s->reg, s->i2c_cycle ++);
  350. }
  351. static int lm_i2c_tx(I2CSlave *i2c, uint8_t data)
  352. {
  353. LM823KbdState *s = (LM823KbdState *) i2c;
  354. if (!s->i2c_cycle)
  355. s->reg = data;
  356. else
  357. lm_kbd_write(s, s->reg, s->i2c_cycle - 1, data);
  358. s->i2c_cycle ++;
  359. return 0;
  360. }
  361. static int lm_kbd_post_load(void *opaque, int version_id)
  362. {
  363. LM823KbdState *s = opaque;
  364. lm_kbd_irq_update(s);
  365. lm_kbd_gpio_update(s);
  366. return 0;
  367. }
  368. static const VMStateDescription vmstate_lm_kbd = {
  369. .name = "LM8323",
  370. .version_id = 0,
  371. .minimum_version_id = 0,
  372. .minimum_version_id_old = 0,
  373. .post_load = lm_kbd_post_load,
  374. .fields = (VMStateField []) {
  375. VMSTATE_I2C_SLAVE(i2c, LM823KbdState),
  376. VMSTATE_UINT8(i2c_dir, LM823KbdState),
  377. VMSTATE_UINT8(i2c_cycle, LM823KbdState),
  378. VMSTATE_UINT8(reg, LM823KbdState),
  379. VMSTATE_UINT8(config, LM823KbdState),
  380. VMSTATE_UINT8(status, LM823KbdState),
  381. VMSTATE_UINT8(acttime, LM823KbdState),
  382. VMSTATE_UINT8(error, LM823KbdState),
  383. VMSTATE_UINT8(clock, LM823KbdState),
  384. VMSTATE_UINT16(gpio.pull, LM823KbdState),
  385. VMSTATE_UINT16(gpio.mask, LM823KbdState),
  386. VMSTATE_UINT16(gpio.dir, LM823KbdState),
  387. VMSTATE_UINT16(gpio.level, LM823KbdState),
  388. VMSTATE_UINT8(kbd.dbnctime, LM823KbdState),
  389. VMSTATE_UINT8(kbd.size, LM823KbdState),
  390. VMSTATE_UINT8(kbd.start, LM823KbdState),
  391. VMSTATE_UINT8(kbd.len, LM823KbdState),
  392. VMSTATE_BUFFER(kbd.fifo, LM823KbdState),
  393. VMSTATE_UINT16_ARRAY(pwm.file, LM823KbdState, 256),
  394. VMSTATE_UINT8(pwm.faddr, LM823KbdState),
  395. VMSTATE_BUFFER(pwm.addr, LM823KbdState),
  396. VMSTATE_TIMER_ARRAY(pwm.tm, LM823KbdState, 3),
  397. VMSTATE_END_OF_LIST()
  398. }
  399. };
  400. static int lm8323_init(I2CSlave *i2c)
  401. {
  402. LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
  403. s->model = 0x8323;
  404. s->pwm.tm[0] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm0_tick, s);
  405. s->pwm.tm[1] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm1_tick, s);
  406. s->pwm.tm[2] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm2_tick, s);
  407. qdev_init_gpio_out(&i2c->qdev, &s->nirq, 1);
  408. lm_kbd_reset(s);
  409. qemu_register_reset((void *) lm_kbd_reset, s);
  410. return 0;
  411. }
  412. void lm832x_key_event(DeviceState *dev, int key, int state)
  413. {
  414. LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, I2C_SLAVE(dev));
  415. if ((s->status & INT_ERROR) && (s->error & ERR_FIFOOVR))
  416. return;
  417. if (s->kbd.len >= sizeof(s->kbd.fifo)) {
  418. lm_kbd_error(s, ERR_FIFOOVR);
  419. return;
  420. }
  421. s->kbd.fifo[(s->kbd.start + s->kbd.len ++) & (sizeof(s->kbd.fifo) - 1)] =
  422. key | (state << 7);
  423. /* We never set ERR_KEYOVR because we support multiple keys fine. */
  424. s->status |= INT_KEYPAD;
  425. lm_kbd_irq_update(s);
  426. }
  427. static void lm8323_class_init(ObjectClass *klass, void *data)
  428. {
  429. DeviceClass *dc = DEVICE_CLASS(klass);
  430. I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
  431. k->init = lm8323_init;
  432. k->event = lm_i2c_event;
  433. k->recv = lm_i2c_rx;
  434. k->send = lm_i2c_tx;
  435. dc->vmsd = &vmstate_lm_kbd;
  436. }
  437. static const TypeInfo lm8323_info = {
  438. .name = "lm8323",
  439. .parent = TYPE_I2C_SLAVE,
  440. .instance_size = sizeof(LM823KbdState),
  441. .class_init = lm8323_class_init,
  442. };
  443. static void lm832x_register_types(void)
  444. {
  445. type_register_static(&lm8323_info);
  446. }
  447. type_init(lm832x_register_types)