core.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. /*
  2. * Silicon Labs C2 port core Linux support
  3. *
  4. * Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it>
  5. * Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it>
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License version 2 as published by
  9. * the Free Software Foundation
  10. */
  11. #include <linux/module.h>
  12. #include <linux/init.h>
  13. #include <linux/device.h>
  14. #include <linux/errno.h>
  15. #include <linux/err.h>
  16. #include <linux/kernel.h>
  17. #include <linux/kmemcheck.h>
  18. #include <linux/ctype.h>
  19. #include <linux/delay.h>
  20. #include <linux/idr.h>
  21. #include <linux/sched.h>
  22. #include <linux/c2port.h>
  23. #define DRIVER_NAME "c2port"
  24. #define DRIVER_VERSION "0.51.0"
  25. static DEFINE_SPINLOCK(c2port_idr_lock);
  26. static DEFINE_IDR(c2port_idr);
  27. /*
  28. * Local variables
  29. */
  30. static struct class *c2port_class;
  31. /*
  32. * C2 registers & commands defines
  33. */
  34. /* C2 registers */
  35. #define C2PORT_DEVICEID 0x00
  36. #define C2PORT_REVID 0x01
  37. #define C2PORT_FPCTL 0x02
  38. #define C2PORT_FPDAT 0xB4
  39. /* C2 interface commands */
  40. #define C2PORT_GET_VERSION 0x01
  41. #define C2PORT_DEVICE_ERASE 0x03
  42. #define C2PORT_BLOCK_READ 0x06
  43. #define C2PORT_BLOCK_WRITE 0x07
  44. #define C2PORT_PAGE_ERASE 0x08
  45. /* C2 status return codes */
  46. #define C2PORT_INVALID_COMMAND 0x00
  47. #define C2PORT_COMMAND_FAILED 0x02
  48. #define C2PORT_COMMAND_OK 0x0d
  49. /*
  50. * C2 port low level signal managements
  51. */
  52. static void c2port_reset(struct c2port_device *dev)
  53. {
  54. struct c2port_ops *ops = dev->ops;
  55. /* To reset the device we have to keep clock line low for at least
  56. * 20us.
  57. */
  58. local_irq_disable();
  59. ops->c2ck_set(dev, 0);
  60. udelay(25);
  61. ops->c2ck_set(dev, 1);
  62. local_irq_enable();
  63. udelay(1);
  64. }
  65. static void c2port_strobe_ck(struct c2port_device *dev)
  66. {
  67. struct c2port_ops *ops = dev->ops;
  68. /* During hi-low-hi transition we disable local IRQs to avoid
  69. * interructions since C2 port specification says that it must be
  70. * shorter than 5us, otherwise the microcontroller may consider
  71. * it as a reset signal!
  72. */
  73. local_irq_disable();
  74. ops->c2ck_set(dev, 0);
  75. udelay(1);
  76. ops->c2ck_set(dev, 1);
  77. local_irq_enable();
  78. udelay(1);
  79. }
  80. /*
  81. * C2 port basic functions
  82. */
  83. static void c2port_write_ar(struct c2port_device *dev, u8 addr)
  84. {
  85. struct c2port_ops *ops = dev->ops;
  86. int i;
  87. /* START field */
  88. c2port_strobe_ck(dev);
  89. /* INS field (11b, LSB first) */
  90. ops->c2d_dir(dev, 0);
  91. ops->c2d_set(dev, 1);
  92. c2port_strobe_ck(dev);
  93. ops->c2d_set(dev, 1);
  94. c2port_strobe_ck(dev);
  95. /* ADDRESS field */
  96. for (i = 0; i < 8; i++) {
  97. ops->c2d_set(dev, addr & 0x01);
  98. c2port_strobe_ck(dev);
  99. addr >>= 1;
  100. }
  101. /* STOP field */
  102. ops->c2d_dir(dev, 1);
  103. c2port_strobe_ck(dev);
  104. }
  105. static int c2port_read_ar(struct c2port_device *dev, u8 *addr)
  106. {
  107. struct c2port_ops *ops = dev->ops;
  108. int i;
  109. /* START field */
  110. c2port_strobe_ck(dev);
  111. /* INS field (10b, LSB first) */
  112. ops->c2d_dir(dev, 0);
  113. ops->c2d_set(dev, 0);
  114. c2port_strobe_ck(dev);
  115. ops->c2d_set(dev, 1);
  116. c2port_strobe_ck(dev);
  117. /* ADDRESS field */
  118. ops->c2d_dir(dev, 1);
  119. *addr = 0;
  120. for (i = 0; i < 8; i++) {
  121. *addr >>= 1; /* shift in 8-bit ADDRESS field LSB first */
  122. c2port_strobe_ck(dev);
  123. if (ops->c2d_get(dev))
  124. *addr |= 0x80;
  125. }
  126. /* STOP field */
  127. c2port_strobe_ck(dev);
  128. return 0;
  129. }
  130. static int c2port_write_dr(struct c2port_device *dev, u8 data)
  131. {
  132. struct c2port_ops *ops = dev->ops;
  133. int timeout, i;
  134. /* START field */
  135. c2port_strobe_ck(dev);
  136. /* INS field (01b, LSB first) */
  137. ops->c2d_dir(dev, 0);
  138. ops->c2d_set(dev, 1);
  139. c2port_strobe_ck(dev);
  140. ops->c2d_set(dev, 0);
  141. c2port_strobe_ck(dev);
  142. /* LENGTH field (00b, LSB first -> 1 byte) */
  143. ops->c2d_set(dev, 0);
  144. c2port_strobe_ck(dev);
  145. ops->c2d_set(dev, 0);
  146. c2port_strobe_ck(dev);
  147. /* DATA field */
  148. for (i = 0; i < 8; i++) {
  149. ops->c2d_set(dev, data & 0x01);
  150. c2port_strobe_ck(dev);
  151. data >>= 1;
  152. }
  153. /* WAIT field */
  154. ops->c2d_dir(dev, 1);
  155. timeout = 20;
  156. do {
  157. c2port_strobe_ck(dev);
  158. if (ops->c2d_get(dev))
  159. break;
  160. udelay(1);
  161. } while (--timeout > 0);
  162. if (timeout == 0)
  163. return -EIO;
  164. /* STOP field */
  165. c2port_strobe_ck(dev);
  166. return 0;
  167. }
  168. static int c2port_read_dr(struct c2port_device *dev, u8 *data)
  169. {
  170. struct c2port_ops *ops = dev->ops;
  171. int timeout, i;
  172. /* START field */
  173. c2port_strobe_ck(dev);
  174. /* INS field (00b, LSB first) */
  175. ops->c2d_dir(dev, 0);
  176. ops->c2d_set(dev, 0);
  177. c2port_strobe_ck(dev);
  178. ops->c2d_set(dev, 0);
  179. c2port_strobe_ck(dev);
  180. /* LENGTH field (00b, LSB first -> 1 byte) */
  181. ops->c2d_set(dev, 0);
  182. c2port_strobe_ck(dev);
  183. ops->c2d_set(dev, 0);
  184. c2port_strobe_ck(dev);
  185. /* WAIT field */
  186. ops->c2d_dir(dev, 1);
  187. timeout = 20;
  188. do {
  189. c2port_strobe_ck(dev);
  190. if (ops->c2d_get(dev))
  191. break;
  192. udelay(1);
  193. } while (--timeout > 0);
  194. if (timeout == 0)
  195. return -EIO;
  196. /* DATA field */
  197. *data = 0;
  198. for (i = 0; i < 8; i++) {
  199. *data >>= 1; /* shift in 8-bit DATA field LSB first */
  200. c2port_strobe_ck(dev);
  201. if (ops->c2d_get(dev))
  202. *data |= 0x80;
  203. }
  204. /* STOP field */
  205. c2port_strobe_ck(dev);
  206. return 0;
  207. }
  208. static int c2port_poll_in_busy(struct c2port_device *dev)
  209. {
  210. u8 addr;
  211. int ret, timeout = 20;
  212. do {
  213. ret = (c2port_read_ar(dev, &addr));
  214. if (ret < 0)
  215. return -EIO;
  216. if (!(addr & 0x02))
  217. break;
  218. udelay(1);
  219. } while (--timeout > 0);
  220. if (timeout == 0)
  221. return -EIO;
  222. return 0;
  223. }
  224. static int c2port_poll_out_ready(struct c2port_device *dev)
  225. {
  226. u8 addr;
  227. int ret, timeout = 10000; /* erase flash needs long time... */
  228. do {
  229. ret = (c2port_read_ar(dev, &addr));
  230. if (ret < 0)
  231. return -EIO;
  232. if (addr & 0x01)
  233. break;
  234. udelay(1);
  235. } while (--timeout > 0);
  236. if (timeout == 0)
  237. return -EIO;
  238. return 0;
  239. }
  240. /*
  241. * sysfs methods
  242. */
  243. static ssize_t c2port_show_name(struct device *dev,
  244. struct device_attribute *attr, char *buf)
  245. {
  246. struct c2port_device *c2dev = dev_get_drvdata(dev);
  247. return sprintf(buf, "%s\n", c2dev->name);
  248. }
  249. static ssize_t c2port_show_flash_blocks_num(struct device *dev,
  250. struct device_attribute *attr, char *buf)
  251. {
  252. struct c2port_device *c2dev = dev_get_drvdata(dev);
  253. struct c2port_ops *ops = c2dev->ops;
  254. return sprintf(buf, "%d\n", ops->blocks_num);
  255. }
  256. static ssize_t c2port_show_flash_block_size(struct device *dev,
  257. struct device_attribute *attr, char *buf)
  258. {
  259. struct c2port_device *c2dev = dev_get_drvdata(dev);
  260. struct c2port_ops *ops = c2dev->ops;
  261. return sprintf(buf, "%d\n", ops->block_size);
  262. }
  263. static ssize_t c2port_show_flash_size(struct device *dev,
  264. struct device_attribute *attr, char *buf)
  265. {
  266. struct c2port_device *c2dev = dev_get_drvdata(dev);
  267. struct c2port_ops *ops = c2dev->ops;
  268. return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
  269. }
  270. static ssize_t c2port_show_access(struct device *dev,
  271. struct device_attribute *attr, char *buf)
  272. {
  273. struct c2port_device *c2dev = dev_get_drvdata(dev);
  274. return sprintf(buf, "%d\n", c2dev->access);
  275. }
  276. static ssize_t c2port_store_access(struct device *dev,
  277. struct device_attribute *attr,
  278. const char *buf, size_t count)
  279. {
  280. struct c2port_device *c2dev = dev_get_drvdata(dev);
  281. struct c2port_ops *ops = c2dev->ops;
  282. int status, ret;
  283. ret = sscanf(buf, "%d", &status);
  284. if (ret != 1)
  285. return -EINVAL;
  286. mutex_lock(&c2dev->mutex);
  287. c2dev->access = !!status;
  288. /* If access is "on" clock should be HIGH _before_ setting the line
  289. * as output and data line should be set as INPUT anyway */
  290. if (c2dev->access)
  291. ops->c2ck_set(c2dev, 1);
  292. ops->access(c2dev, c2dev->access);
  293. if (c2dev->access)
  294. ops->c2d_dir(c2dev, 1);
  295. mutex_unlock(&c2dev->mutex);
  296. return count;
  297. }
  298. static ssize_t c2port_store_reset(struct device *dev,
  299. struct device_attribute *attr,
  300. const char *buf, size_t count)
  301. {
  302. struct c2port_device *c2dev = dev_get_drvdata(dev);
  303. /* Check the device access status */
  304. if (!c2dev->access)
  305. return -EBUSY;
  306. mutex_lock(&c2dev->mutex);
  307. c2port_reset(c2dev);
  308. c2dev->flash_access = 0;
  309. mutex_unlock(&c2dev->mutex);
  310. return count;
  311. }
  312. static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
  313. {
  314. u8 data;
  315. int ret;
  316. /* Select DEVICEID register for C2 data register accesses */
  317. c2port_write_ar(dev, C2PORT_DEVICEID);
  318. /* Read and return the device ID register */
  319. ret = c2port_read_dr(dev, &data);
  320. if (ret < 0)
  321. return ret;
  322. return sprintf(buf, "%d\n", data);
  323. }
  324. static ssize_t c2port_show_dev_id(struct device *dev,
  325. struct device_attribute *attr, char *buf)
  326. {
  327. struct c2port_device *c2dev = dev_get_drvdata(dev);
  328. ssize_t ret;
  329. /* Check the device access status */
  330. if (!c2dev->access)
  331. return -EBUSY;
  332. mutex_lock(&c2dev->mutex);
  333. ret = __c2port_show_dev_id(c2dev, buf);
  334. mutex_unlock(&c2dev->mutex);
  335. if (ret < 0)
  336. dev_err(dev, "cannot read from %s\n", c2dev->name);
  337. return ret;
  338. }
  339. static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
  340. {
  341. u8 data;
  342. int ret;
  343. /* Select REVID register for C2 data register accesses */
  344. c2port_write_ar(dev, C2PORT_REVID);
  345. /* Read and return the revision ID register */
  346. ret = c2port_read_dr(dev, &data);
  347. if (ret < 0)
  348. return ret;
  349. return sprintf(buf, "%d\n", data);
  350. }
  351. static ssize_t c2port_show_rev_id(struct device *dev,
  352. struct device_attribute *attr, char *buf)
  353. {
  354. struct c2port_device *c2dev = dev_get_drvdata(dev);
  355. ssize_t ret;
  356. /* Check the device access status */
  357. if (!c2dev->access)
  358. return -EBUSY;
  359. mutex_lock(&c2dev->mutex);
  360. ret = __c2port_show_rev_id(c2dev, buf);
  361. mutex_unlock(&c2dev->mutex);
  362. if (ret < 0)
  363. dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name);
  364. return ret;
  365. }
  366. static ssize_t c2port_show_flash_access(struct device *dev,
  367. struct device_attribute *attr, char *buf)
  368. {
  369. struct c2port_device *c2dev = dev_get_drvdata(dev);
  370. return sprintf(buf, "%d\n", c2dev->flash_access);
  371. }
  372. static ssize_t __c2port_store_flash_access(struct c2port_device *dev,
  373. int status)
  374. {
  375. int ret;
  376. /* Check the device access status */
  377. if (!dev->access)
  378. return -EBUSY;
  379. dev->flash_access = !!status;
  380. /* If flash_access is off we have nothing to do... */
  381. if (dev->flash_access == 0)
  382. return 0;
  383. /* Target the C2 flash programming control register for C2 data
  384. * register access */
  385. c2port_write_ar(dev, C2PORT_FPCTL);
  386. /* Write the first keycode to enable C2 Flash programming */
  387. ret = c2port_write_dr(dev, 0x02);
  388. if (ret < 0)
  389. return ret;
  390. /* Write the second keycode to enable C2 Flash programming */
  391. ret = c2port_write_dr(dev, 0x01);
  392. if (ret < 0)
  393. return ret;
  394. /* Delay for at least 20ms to ensure the target is ready for
  395. * C2 flash programming */
  396. mdelay(25);
  397. return 0;
  398. }
  399. static ssize_t c2port_store_flash_access(struct device *dev,
  400. struct device_attribute *attr,
  401. const char *buf, size_t count)
  402. {
  403. struct c2port_device *c2dev = dev_get_drvdata(dev);
  404. int status;
  405. ssize_t ret;
  406. ret = sscanf(buf, "%d", &status);
  407. if (ret != 1)
  408. return -EINVAL;
  409. mutex_lock(&c2dev->mutex);
  410. ret = __c2port_store_flash_access(c2dev, status);
  411. mutex_unlock(&c2dev->mutex);
  412. if (ret < 0) {
  413. dev_err(c2dev->dev, "cannot enable %s flash programming\n",
  414. c2dev->name);
  415. return ret;
  416. }
  417. return count;
  418. }
  419. static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
  420. {
  421. u8 status;
  422. int ret;
  423. /* Target the C2 flash programming data register for C2 data register
  424. * access.
  425. */
  426. c2port_write_ar(dev, C2PORT_FPDAT);
  427. /* Send device erase command */
  428. c2port_write_dr(dev, C2PORT_DEVICE_ERASE);
  429. /* Wait for input acknowledge */
  430. ret = c2port_poll_in_busy(dev);
  431. if (ret < 0)
  432. return ret;
  433. /* Should check status before starting FLASH access sequence */
  434. /* Wait for status information */
  435. ret = c2port_poll_out_ready(dev);
  436. if (ret < 0)
  437. return ret;
  438. /* Read flash programming interface status */
  439. ret = c2port_read_dr(dev, &status);
  440. if (ret < 0)
  441. return ret;
  442. if (status != C2PORT_COMMAND_OK)
  443. return -EBUSY;
  444. /* Send a three-byte arming sequence to enable the device erase.
  445. * If the sequence is not received correctly, the command will be
  446. * ignored.
  447. * Sequence is: 0xde, 0xad, 0xa5.
  448. */
  449. c2port_write_dr(dev, 0xde);
  450. ret = c2port_poll_in_busy(dev);
  451. if (ret < 0)
  452. return ret;
  453. c2port_write_dr(dev, 0xad);
  454. ret = c2port_poll_in_busy(dev);
  455. if (ret < 0)
  456. return ret;
  457. c2port_write_dr(dev, 0xa5);
  458. ret = c2port_poll_in_busy(dev);
  459. if (ret < 0)
  460. return ret;
  461. ret = c2port_poll_out_ready(dev);
  462. if (ret < 0)
  463. return ret;
  464. return 0;
  465. }
  466. static ssize_t c2port_store_flash_erase(struct device *dev,
  467. struct device_attribute *attr,
  468. const char *buf, size_t count)
  469. {
  470. struct c2port_device *c2dev = dev_get_drvdata(dev);
  471. int ret;
  472. /* Check the device and flash access status */
  473. if (!c2dev->access || !c2dev->flash_access)
  474. return -EBUSY;
  475. mutex_lock(&c2dev->mutex);
  476. ret = __c2port_write_flash_erase(c2dev);
  477. mutex_unlock(&c2dev->mutex);
  478. if (ret < 0) {
  479. dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name);
  480. return ret;
  481. }
  482. return count;
  483. }
  484. static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
  485. char *buffer, loff_t offset, size_t count)
  486. {
  487. struct c2port_ops *ops = dev->ops;
  488. u8 status, nread = 128;
  489. int i, ret;
  490. /* Check for flash end */
  491. if (offset >= ops->block_size * ops->blocks_num)
  492. return 0;
  493. if (ops->block_size * ops->blocks_num - offset < nread)
  494. nread = ops->block_size * ops->blocks_num - offset;
  495. if (count < nread)
  496. nread = count;
  497. if (nread == 0)
  498. return nread;
  499. /* Target the C2 flash programming data register for C2 data register
  500. * access */
  501. c2port_write_ar(dev, C2PORT_FPDAT);
  502. /* Send flash block read command */
  503. c2port_write_dr(dev, C2PORT_BLOCK_READ);
  504. /* Wait for input acknowledge */
  505. ret = c2port_poll_in_busy(dev);
  506. if (ret < 0)
  507. return ret;
  508. /* Should check status before starting FLASH access sequence */
  509. /* Wait for status information */
  510. ret = c2port_poll_out_ready(dev);
  511. if (ret < 0)
  512. return ret;
  513. /* Read flash programming interface status */
  514. ret = c2port_read_dr(dev, &status);
  515. if (ret < 0)
  516. return ret;
  517. if (status != C2PORT_COMMAND_OK)
  518. return -EBUSY;
  519. /* Send address high byte */
  520. c2port_write_dr(dev, offset >> 8);
  521. ret = c2port_poll_in_busy(dev);
  522. if (ret < 0)
  523. return ret;
  524. /* Send address low byte */
  525. c2port_write_dr(dev, offset & 0x00ff);
  526. ret = c2port_poll_in_busy(dev);
  527. if (ret < 0)
  528. return ret;
  529. /* Send address block size */
  530. c2port_write_dr(dev, nread);
  531. ret = c2port_poll_in_busy(dev);
  532. if (ret < 0)
  533. return ret;
  534. /* Should check status before reading FLASH block */
  535. /* Wait for status information */
  536. ret = c2port_poll_out_ready(dev);
  537. if (ret < 0)
  538. return ret;
  539. /* Read flash programming interface status */
  540. ret = c2port_read_dr(dev, &status);
  541. if (ret < 0)
  542. return ret;
  543. if (status != C2PORT_COMMAND_OK)
  544. return -EBUSY;
  545. /* Read flash block */
  546. for (i = 0; i < nread; i++) {
  547. ret = c2port_poll_out_ready(dev);
  548. if (ret < 0)
  549. return ret;
  550. ret = c2port_read_dr(dev, buffer+i);
  551. if (ret < 0)
  552. return ret;
  553. }
  554. return nread;
  555. }
  556. static ssize_t c2port_read_flash_data(struct kobject *kobj,
  557. struct bin_attribute *attr,
  558. char *buffer, loff_t offset, size_t count)
  559. {
  560. struct c2port_device *c2dev =
  561. dev_get_drvdata(container_of(kobj,
  562. struct device, kobj));
  563. ssize_t ret;
  564. /* Check the device and flash access status */
  565. if (!c2dev->access || !c2dev->flash_access)
  566. return -EBUSY;
  567. mutex_lock(&c2dev->mutex);
  568. ret = __c2port_read_flash_data(c2dev, buffer, offset, count);
  569. mutex_unlock(&c2dev->mutex);
  570. if (ret < 0)
  571. dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name);
  572. return ret;
  573. }
  574. static ssize_t __c2port_write_flash_data(struct c2port_device *dev,
  575. char *buffer, loff_t offset, size_t count)
  576. {
  577. struct c2port_ops *ops = dev->ops;
  578. u8 status, nwrite = 128;
  579. int i, ret;
  580. if (nwrite > count)
  581. nwrite = count;
  582. if (ops->block_size * ops->blocks_num - offset < nwrite)
  583. nwrite = ops->block_size * ops->blocks_num - offset;
  584. /* Check for flash end */
  585. if (offset >= ops->block_size * ops->blocks_num)
  586. return -EINVAL;
  587. /* Target the C2 flash programming data register for C2 data register
  588. * access */
  589. c2port_write_ar(dev, C2PORT_FPDAT);
  590. /* Send flash block write command */
  591. c2port_write_dr(dev, C2PORT_BLOCK_WRITE);
  592. /* Wait for input acknowledge */
  593. ret = c2port_poll_in_busy(dev);
  594. if (ret < 0)
  595. return ret;
  596. /* Should check status before starting FLASH access sequence */
  597. /* Wait for status information */
  598. ret = c2port_poll_out_ready(dev);
  599. if (ret < 0)
  600. return ret;
  601. /* Read flash programming interface status */
  602. ret = c2port_read_dr(dev, &status);
  603. if (ret < 0)
  604. return ret;
  605. if (status != C2PORT_COMMAND_OK)
  606. return -EBUSY;
  607. /* Send address high byte */
  608. c2port_write_dr(dev, offset >> 8);
  609. ret = c2port_poll_in_busy(dev);
  610. if (ret < 0)
  611. return ret;
  612. /* Send address low byte */
  613. c2port_write_dr(dev, offset & 0x00ff);
  614. ret = c2port_poll_in_busy(dev);
  615. if (ret < 0)
  616. return ret;
  617. /* Send address block size */
  618. c2port_write_dr(dev, nwrite);
  619. ret = c2port_poll_in_busy(dev);
  620. if (ret < 0)
  621. return ret;
  622. /* Should check status before writing FLASH block */
  623. /* Wait for status information */
  624. ret = c2port_poll_out_ready(dev);
  625. if (ret < 0)
  626. return ret;
  627. /* Read flash programming interface status */
  628. ret = c2port_read_dr(dev, &status);
  629. if (ret < 0)
  630. return ret;
  631. if (status != C2PORT_COMMAND_OK)
  632. return -EBUSY;
  633. /* Write flash block */
  634. for (i = 0; i < nwrite; i++) {
  635. ret = c2port_write_dr(dev, *(buffer+i));
  636. if (ret < 0)
  637. return ret;
  638. ret = c2port_poll_in_busy(dev);
  639. if (ret < 0)
  640. return ret;
  641. }
  642. /* Wait for last flash write to complete */
  643. ret = c2port_poll_out_ready(dev);
  644. if (ret < 0)
  645. return ret;
  646. return nwrite;
  647. }
  648. static ssize_t c2port_write_flash_data(struct kobject *kobj,
  649. struct bin_attribute *attr,
  650. char *buffer, loff_t offset, size_t count)
  651. {
  652. struct c2port_device *c2dev =
  653. dev_get_drvdata(container_of(kobj,
  654. struct device, kobj));
  655. int ret;
  656. /* Check the device access status */
  657. if (!c2dev->access || !c2dev->flash_access)
  658. return -EBUSY;
  659. mutex_lock(&c2dev->mutex);
  660. ret = __c2port_write_flash_data(c2dev, buffer, offset, count);
  661. mutex_unlock(&c2dev->mutex);
  662. if (ret < 0)
  663. dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name);
  664. return ret;
  665. }
  666. /*
  667. * Class attributes
  668. */
  669. static struct device_attribute c2port_attrs[] = {
  670. __ATTR(name, 0444, c2port_show_name, NULL),
  671. __ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL),
  672. __ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL),
  673. __ATTR(flash_size, 0444, c2port_show_flash_size, NULL),
  674. __ATTR(access, 0644, c2port_show_access, c2port_store_access),
  675. __ATTR(reset, 0200, NULL, c2port_store_reset),
  676. __ATTR(dev_id, 0444, c2port_show_dev_id, NULL),
  677. __ATTR(rev_id, 0444, c2port_show_rev_id, NULL),
  678. __ATTR(flash_access, 0644, c2port_show_flash_access,
  679. c2port_store_flash_access),
  680. __ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase),
  681. __ATTR_NULL,
  682. };
  683. static struct bin_attribute c2port_bin_attrs = {
  684. .attr = {
  685. .name = "flash_data",
  686. .mode = 0644
  687. },
  688. .read = c2port_read_flash_data,
  689. .write = c2port_write_flash_data,
  690. /* .size is computed at run-time */
  691. };
  692. /*
  693. * Exported functions
  694. */
  695. struct c2port_device *c2port_device_register(char *name,
  696. struct c2port_ops *ops, void *devdata)
  697. {
  698. struct c2port_device *c2dev;
  699. int id, ret;
  700. if (unlikely(!ops) || unlikely(!ops->access) || \
  701. unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
  702. unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set))
  703. return ERR_PTR(-EINVAL);
  704. c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL);
  705. kmemcheck_annotate_bitfield(c2dev, flags);
  706. if (unlikely(!c2dev))
  707. return ERR_PTR(-ENOMEM);
  708. ret = idr_pre_get(&c2port_idr, GFP_KERNEL);
  709. if (!ret) {
  710. ret = -ENOMEM;
  711. goto error_idr_get_new;
  712. }
  713. spin_lock_irq(&c2port_idr_lock);
  714. ret = idr_get_new(&c2port_idr, c2dev, &id);
  715. spin_unlock_irq(&c2port_idr_lock);
  716. if (ret < 0)
  717. goto error_idr_get_new;
  718. c2dev->id = id;
  719. c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
  720. "c2port%d", id);
  721. if (unlikely(!c2dev->dev)) {
  722. ret = -ENOMEM;
  723. goto error_device_create;
  724. }
  725. dev_set_drvdata(c2dev->dev, c2dev);
  726. strncpy(c2dev->name, name, C2PORT_NAME_LEN);
  727. c2dev->ops = ops;
  728. mutex_init(&c2dev->mutex);
  729. /* Create binary file */
  730. c2port_bin_attrs.size = ops->blocks_num * ops->block_size;
  731. ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs);
  732. if (unlikely(ret))
  733. goto error_device_create_bin_file;
  734. /* By default C2 port access is off */
  735. c2dev->access = c2dev->flash_access = 0;
  736. ops->access(c2dev, 0);
  737. dev_info(c2dev->dev, "C2 port %s added\n", name);
  738. dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes "
  739. "(%d bytes total)\n",
  740. name, ops->blocks_num, ops->block_size,
  741. ops->blocks_num * ops->block_size);
  742. return c2dev;
  743. error_device_create_bin_file:
  744. device_destroy(c2port_class, 0);
  745. error_device_create:
  746. spin_lock_irq(&c2port_idr_lock);
  747. idr_remove(&c2port_idr, id);
  748. spin_unlock_irq(&c2port_idr_lock);
  749. error_idr_get_new:
  750. kfree(c2dev);
  751. return ERR_PTR(ret);
  752. }
  753. EXPORT_SYMBOL(c2port_device_register);
  754. void c2port_device_unregister(struct c2port_device *c2dev)
  755. {
  756. if (!c2dev)
  757. return;
  758. dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
  759. device_remove_bin_file(c2dev->dev, &c2port_bin_attrs);
  760. spin_lock_irq(&c2port_idr_lock);
  761. idr_remove(&c2port_idr, c2dev->id);
  762. spin_unlock_irq(&c2port_idr_lock);
  763. device_destroy(c2port_class, c2dev->id);
  764. kfree(c2dev);
  765. }
  766. EXPORT_SYMBOL(c2port_device_unregister);
  767. /*
  768. * Module stuff
  769. */
  770. static int __init c2port_init(void)
  771. {
  772. printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION
  773. " - (C) 2007 Rodolfo Giometti\n");
  774. c2port_class = class_create(THIS_MODULE, "c2port");
  775. if (!c2port_class) {
  776. printk(KERN_ERR "c2port: failed to allocate class\n");
  777. return -ENOMEM;
  778. }
  779. c2port_class->dev_attrs = c2port_attrs;
  780. return 0;
  781. }
  782. static void __exit c2port_exit(void)
  783. {
  784. class_destroy(c2port_class);
  785. }
  786. module_init(c2port_init);
  787. module_exit(c2port_exit);
  788. MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
  789. MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION);
  790. MODULE_LICENSE("GPL");