Advertisement
Guest User

Untitled

a guest
Aug 24th, 2017
449
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 55.52 KB | None | 0 0
  1. From c588a38519e40284de9aa980131930236e14b07c Mon Sep 17 00:00:00 2001
  2. From: Evan J Brunner <ej3@appitto.me>
  3. Date: Fri, 31 Oct 2014 11:05:39 -0700
  4. Subject: [PATCH] c2port: remove duramar2150, add GPIO
  5.  
  6. CHNGD:c2port-core had somehow came to be
  7. called simply 'core' which was an
  8. ambigious name for a module, so name
  9. was reverted
  10. CHNGD:duramar client was not relevant, replaced
  11. with GENERIC_GPIO client
  12. ---
  13. drivers/misc/Makefile | 2 +-
  14. drivers/misc/c2port/Kconfig | 19 +-
  15. drivers/misc/c2port/Makefile | 5 +-
  16. drivers/misc/c2port/c2port-core.c | 1009 ++++++++++++++++++++++++++++++
  17. drivers/misc/c2port/c2port-duramar2150.c | 159 -----
  18. drivers/misc/c2port/c2port-gpio.c | 125 ++++
  19. drivers/misc/c2port/core.c | 1009 ------------------------------
  20. 7 files changed, 1146 insertions(+), 1182 deletions(-)
  21. create mode 100644 drivers/misc/c2port/c2port-core.c
  22. delete mode 100644 drivers/misc/c2port/c2port-duramar2150.c
  23. create mode 100644 drivers/misc/c2port/c2port-gpio.c
  24. delete mode 100644 drivers/misc/c2port/core.c
  25.  
  26. diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
  27. index 24b40c3..5e5c23c 100644
  28. --- a/drivers/misc/Makefile
  29. +++ b/drivers/misc/Makefile
  30. @@ -36,7 +36,7 @@ obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
  31. obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
  32. obj-$(CONFIG_DS1682) += ds1682.o
  33. obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
  34. -obj-$(CONFIG_C2PORT) += c2port/
  35. +obj-$(CONFIG_C2PORT_CORE) += c2port/
  36. obj-$(CONFIG_HMC6352) += hmc6352.o
  37. obj-y += eeprom/
  38. obj-y += cb710/
  39. diff --git a/drivers/misc/c2port/Kconfig b/drivers/misc/c2port/Kconfig
  40. index 0dd690e..b86bf6d 100644
  41. --- a/drivers/misc/c2port/Kconfig
  42. +++ b/drivers/misc/c2port/Kconfig
  43. @@ -2,7 +2,8 @@
  44. # C2 port devices
  45. #
  46.  
  47. -menuconfig C2PORT
  48. +menu C2PORT
  49. +config C2PORT_CORE
  50. tristate "Silicon Labs C2 port support"
  51. default n
  52. help
  53. @@ -18,17 +19,15 @@ menuconfig C2PORT
  54.  
  55. If you are not sure, say N here.
  56.  
  57. -if C2PORT
  58.  
  59. -config C2PORT_DURAMAR_2150
  60. - tristate "C2 port support for Eurotech's Duramar 2150"
  61. - depends on X86
  62. +config C2PORT_GPIO
  63. + tristate "C2 port support generic GPIO"
  64. + depends on GPIO_SYSFS
  65. default n
  66. help
  67. - This option enables C2 support for the Eurotech's Duramar 2150
  68. - on board micro controller.
  69. + This option enables C2 support for the c2port on a generic
  70. + gpio interface, using 'bit-banging'.
  71.  
  72. To compile this driver as a module, choose M here: the module will
  73. - be called c2port-duramar2150.
  74. -
  75. -endif # C2PORT
  76. + be called c2port-gpio.
  77. +endmenu
  78. diff --git a/drivers/misc/c2port/Makefile b/drivers/misc/c2port/Makefile
  79. index 3b2cf43..77d90bd 100644
  80. --- a/drivers/misc/c2port/Makefile
  81. +++ b/drivers/misc/c2port/Makefile
  82. @@ -1,3 +1,2 @@
  83. -obj-$(CONFIG_C2PORT) += core.o
  84. -
  85. -obj-$(CONFIG_C2PORT_DURAMAR_2150) += c2port-duramar2150.o
  86. +obj-$(CONFIG_C2PORT_CORE) += c2port-core.o
  87. +obj-${CONFIG_C2PORT_GPIO} += c2port-gpio.o
  88. diff --git a/drivers/misc/c2port/c2port-core.c b/drivers/misc/c2port/c2port-core.c
  89. new file mode 100644
  90. index 0000000..464419b
  91. --- /dev/null
  92. +++ b/drivers/misc/c2port/c2port-core.c
  93. @@ -0,0 +1,1009 @@
  94. +/*
  95. + * Silicon Labs C2 port core Linux support
  96. + *
  97. + * Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it>
  98. + * Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it>
  99. + *
  100. + * This program is free software; you can redistribute it and/or modify it
  101. + * under the terms of the GNU General Public License version 2 as published by
  102. + * the Free Software Foundation
  103. + */
  104. +
  105. +#include <linux/module.h>
  106. +#include <linux/init.h>
  107. +#include <linux/device.h>
  108. +#include <linux/errno.h>
  109. +#include <linux/err.h>
  110. +#include <linux/kernel.h>
  111. +#include <linux/kmemcheck.h>
  112. +#include <linux/ctype.h>
  113. +#include <linux/delay.h>
  114. +#include <linux/idr.h>
  115. +#include <linux/sched.h>
  116. +#include <linux/slab.h>
  117. +
  118. +#include <linux/c2port.h>
  119. +
  120. +#define DRIVER_NAME "c2port"
  121. +#define DRIVER_VERSION "0.51.0"
  122. +
  123. +static DEFINE_SPINLOCK(c2port_idr_lock);
  124. +static DEFINE_IDR(c2port_idr);
  125. +
  126. +/*
  127. + * Local variables
  128. + */
  129. +
  130. +static struct class *c2port_class;
  131. +
  132. +/*
  133. + * C2 registers & commands defines
  134. + */
  135. +
  136. +/* C2 registers */
  137. +#define C2PORT_DEVICEID 0x00
  138. +#define C2PORT_REVID 0x01
  139. +#define C2PORT_FPCTL 0x02
  140. +#define C2PORT_FPDAT 0xB4
  141. +
  142. +/* C2 interface commands */
  143. +#define C2PORT_GET_VERSION 0x01
  144. +#define C2PORT_DEVICE_ERASE 0x03
  145. +#define C2PORT_BLOCK_READ 0x06
  146. +#define C2PORT_BLOCK_WRITE 0x07
  147. +#define C2PORT_PAGE_ERASE 0x08
  148. +
  149. +/* C2 status return codes */
  150. +#define C2PORT_INVALID_COMMAND 0x00
  151. +#define C2PORT_COMMAND_FAILED 0x02
  152. +#define C2PORT_COMMAND_OK 0x0d
  153. +
  154. +/*
  155. + * C2 port low level signal managements
  156. + */
  157. +
  158. +static void c2port_reset(struct c2port_device *dev)
  159. +{
  160. + struct c2port_ops *ops = dev->ops;
  161. +
  162. + /* To reset the device we have to keep clock line low for at least
  163. + * 20us.
  164. + */
  165. + local_irq_disable();
  166. + ops->c2ck_set(dev, 0);
  167. + udelay(25);
  168. + ops->c2ck_set(dev, 1);
  169. + local_irq_enable();
  170. +
  171. + udelay(1);
  172. +}
  173. +
  174. +static void c2port_strobe_ck(struct c2port_device *dev)
  175. +{
  176. + struct c2port_ops *ops = dev->ops;
  177. +
  178. + /* During hi-low-hi transition we disable local IRQs to avoid
  179. + * interructions since C2 port specification says that it must be
  180. + * shorter than 5us, otherwise the microcontroller may consider
  181. + * it as a reset signal!
  182. + */
  183. + local_irq_disable();
  184. + ops->c2ck_set(dev, 0);
  185. + udelay(1);
  186. + ops->c2ck_set(dev, 1);
  187. + local_irq_enable();
  188. +
  189. + udelay(1);
  190. +}
  191. +
  192. +/*
  193. + * C2 port basic functions
  194. + */
  195. +
  196. +static void c2port_write_ar(struct c2port_device *dev, u8 addr)
  197. +{
  198. + struct c2port_ops *ops = dev->ops;
  199. + int i;
  200. +
  201. + /* START field */
  202. + c2port_strobe_ck(dev);
  203. +
  204. + /* INS field (11b, LSB first) */
  205. + ops->c2d_dir(dev, 0);
  206. + ops->c2d_set(dev, 1);
  207. + c2port_strobe_ck(dev);
  208. + ops->c2d_set(dev, 1);
  209. + c2port_strobe_ck(dev);
  210. +
  211. + /* ADDRESS field */
  212. + for (i = 0; i < 8; i++) {
  213. + ops->c2d_set(dev, addr & 0x01);
  214. + c2port_strobe_ck(dev);
  215. +
  216. + addr >>= 1;
  217. + }
  218. +
  219. + /* STOP field */
  220. + ops->c2d_dir(dev, 1);
  221. + c2port_strobe_ck(dev);
  222. +}
  223. +
  224. +static int c2port_read_ar(struct c2port_device *dev, u8 *addr)
  225. +{
  226. + struct c2port_ops *ops = dev->ops;
  227. + int i;
  228. +
  229. + /* START field */
  230. + c2port_strobe_ck(dev);
  231. +
  232. + /* INS field (10b, LSB first) */
  233. + ops->c2d_dir(dev, 0);
  234. + ops->c2d_set(dev, 0);
  235. + c2port_strobe_ck(dev);
  236. + ops->c2d_set(dev, 1);
  237. + c2port_strobe_ck(dev);
  238. +
  239. + /* ADDRESS field */
  240. + ops->c2d_dir(dev, 1);
  241. + *addr = 0;
  242. + for (i = 0; i < 8; i++) {
  243. + *addr >>= 1; /* shift in 8-bit ADDRESS field LSB first */
  244. +
  245. + c2port_strobe_ck(dev);
  246. + if (ops->c2d_get(dev))
  247. + *addr |= 0x80;
  248. + }
  249. +
  250. + /* STOP field */
  251. + c2port_strobe_ck(dev);
  252. +
  253. + return 0;
  254. +}
  255. +
  256. +static int c2port_write_dr(struct c2port_device *dev, u8 data)
  257. +{
  258. + struct c2port_ops *ops = dev->ops;
  259. + int timeout, i;
  260. +
  261. + /* START field */
  262. + c2port_strobe_ck(dev);
  263. +
  264. + /* INS field (01b, LSB first) */
  265. + ops->c2d_dir(dev, 0);
  266. + ops->c2d_set(dev, 1);
  267. + c2port_strobe_ck(dev);
  268. + ops->c2d_set(dev, 0);
  269. + c2port_strobe_ck(dev);
  270. +
  271. + /* LENGTH field (00b, LSB first -> 1 byte) */
  272. + ops->c2d_set(dev, 0);
  273. + c2port_strobe_ck(dev);
  274. + ops->c2d_set(dev, 0);
  275. + c2port_strobe_ck(dev);
  276. +
  277. + /* DATA field */
  278. + for (i = 0; i < 8; i++) {
  279. + ops->c2d_set(dev, data & 0x01);
  280. + c2port_strobe_ck(dev);
  281. +
  282. + data >>= 1;
  283. + }
  284. +
  285. + /* WAIT field */
  286. + ops->c2d_dir(dev, 1);
  287. + timeout = 20;
  288. + do {
  289. + c2port_strobe_ck(dev);
  290. + if (ops->c2d_get(dev))
  291. + break;
  292. +
  293. + udelay(1);
  294. + } while (--timeout > 0);
  295. + if (timeout == 0)
  296. + return -EIO;
  297. +
  298. + /* STOP field */
  299. + c2port_strobe_ck(dev);
  300. +
  301. + return 0;
  302. +}
  303. +
  304. +static int c2port_read_dr(struct c2port_device *dev, u8 *data)
  305. +{
  306. + struct c2port_ops *ops = dev->ops;
  307. + int timeout, i;
  308. +
  309. + /* START field */
  310. + c2port_strobe_ck(dev);
  311. +
  312. + /* INS field (00b, LSB first) */
  313. + ops->c2d_dir(dev, 0);
  314. + ops->c2d_set(dev, 0);
  315. + c2port_strobe_ck(dev);
  316. + ops->c2d_set(dev, 0);
  317. + c2port_strobe_ck(dev);
  318. +
  319. + /* LENGTH field (00b, LSB first -> 1 byte) */
  320. + ops->c2d_set(dev, 0);
  321. + c2port_strobe_ck(dev);
  322. + ops->c2d_set(dev, 0);
  323. + c2port_strobe_ck(dev);
  324. +
  325. + /* WAIT field */
  326. + ops->c2d_dir(dev, 1);
  327. + timeout = 20;
  328. + do {
  329. + c2port_strobe_ck(dev);
  330. + if (ops->c2d_get(dev))
  331. + break;
  332. +
  333. + udelay(1);
  334. + } while (--timeout > 0);
  335. + if (timeout == 0)
  336. + return -EIO;
  337. +
  338. + /* DATA field */
  339. + *data = 0;
  340. + for (i = 0; i < 8; i++) {
  341. + *data >>= 1; /* shift in 8-bit DATA field LSB first */
  342. +
  343. + c2port_strobe_ck(dev);
  344. + if (ops->c2d_get(dev))
  345. + *data |= 0x80;
  346. + }
  347. +
  348. + /* STOP field */
  349. + c2port_strobe_ck(dev);
  350. +
  351. + return 0;
  352. +}
  353. +
  354. +static int c2port_poll_in_busy(struct c2port_device *dev)
  355. +{
  356. + u8 addr;
  357. + int ret, timeout = 20;
  358. +
  359. + do {
  360. + ret = (c2port_read_ar(dev, &addr));
  361. + if (ret < 0)
  362. + return -EIO;
  363. +
  364. + if (!(addr & 0x02))
  365. + break;
  366. +
  367. + udelay(1);
  368. + } while (--timeout > 0);
  369. + if (timeout == 0)
  370. + return -EIO;
  371. +
  372. + return 0;
  373. +}
  374. +
  375. +static int c2port_poll_out_ready(struct c2port_device *dev)
  376. +{
  377. + u8 addr;
  378. + int ret, timeout = 10000; /* erase flash needs long time... */
  379. +
  380. + do {
  381. + ret = (c2port_read_ar(dev, &addr));
  382. + if (ret < 0)
  383. + return -EIO;
  384. +
  385. + if (addr & 0x01)
  386. + break;
  387. +
  388. + udelay(1);
  389. + } while (--timeout > 0);
  390. + if (timeout == 0)
  391. + return -EIO;
  392. +
  393. + return 0;
  394. +}
  395. +
  396. +/*
  397. + * sysfs methods
  398. + */
  399. +
  400. +static ssize_t c2port_show_name(struct device *dev,
  401. + struct device_attribute *attr, char *buf)
  402. +{
  403. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  404. +
  405. + return sprintf(buf, "%s\n", c2dev->name);
  406. +}
  407. +static DEVICE_ATTR(name, 0444, c2port_show_name, NULL);
  408. +
  409. +static ssize_t c2port_show_flash_blocks_num(struct device *dev,
  410. + struct device_attribute *attr, char *buf)
  411. +{
  412. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  413. + struct c2port_ops *ops = c2dev->ops;
  414. +
  415. + return sprintf(buf, "%d\n", ops->blocks_num);
  416. +}
  417. +static DEVICE_ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL);
  418. +
  419. +static ssize_t c2port_show_flash_block_size(struct device *dev,
  420. + struct device_attribute *attr, char *buf)
  421. +{
  422. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  423. + struct c2port_ops *ops = c2dev->ops;
  424. +
  425. + return sprintf(buf, "%d\n", ops->block_size);
  426. +}
  427. +static DEVICE_ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL);
  428. +
  429. +static ssize_t c2port_show_flash_size(struct device *dev,
  430. + struct device_attribute *attr, char *buf)
  431. +{
  432. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  433. + struct c2port_ops *ops = c2dev->ops;
  434. +
  435. + return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
  436. +}
  437. +static DEVICE_ATTR(flash_size, 0444, c2port_show_flash_size, NULL);
  438. +
  439. +static ssize_t access_show(struct device *dev, struct device_attribute *attr,
  440. + char *buf)
  441. +{
  442. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  443. +
  444. + return sprintf(buf, "%d\n", c2dev->access);
  445. +}
  446. +
  447. +static ssize_t access_store(struct device *dev, struct device_attribute *attr,
  448. + const char *buf, size_t count)
  449. +{
  450. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  451. + struct c2port_ops *ops = c2dev->ops;
  452. + int status, ret;
  453. +
  454. + ret = sscanf(buf, "%d", &status);
  455. + if (ret != 1)
  456. + return -EINVAL;
  457. +
  458. + mutex_lock(&c2dev->mutex);
  459. +
  460. + c2dev->access = !!status;
  461. +
  462. + /* If access is "on" clock should be HIGH _before_ setting the line
  463. + * as output and data line should be set as INPUT anyway */
  464. + if (c2dev->access)
  465. + ops->c2ck_set(c2dev, 1);
  466. + ops->access(c2dev, c2dev->access);
  467. + if (c2dev->access)
  468. + ops->c2d_dir(c2dev, 1);
  469. +
  470. + mutex_unlock(&c2dev->mutex);
  471. +
  472. + return count;
  473. +}
  474. +static DEVICE_ATTR_RW(access);
  475. +
  476. +static ssize_t c2port_store_reset(struct device *dev,
  477. + struct device_attribute *attr,
  478. + const char *buf, size_t count)
  479. +{
  480. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  481. +
  482. + /* Check the device access status */
  483. + if (!c2dev->access)
  484. + return -EBUSY;
  485. +
  486. + mutex_lock(&c2dev->mutex);
  487. +
  488. + c2port_reset(c2dev);
  489. + c2dev->flash_access = 0;
  490. +
  491. + mutex_unlock(&c2dev->mutex);
  492. +
  493. + return count;
  494. +}
  495. +static DEVICE_ATTR(reset, 0200, NULL, c2port_store_reset);
  496. +
  497. +static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
  498. +{
  499. + u8 data;
  500. + int ret;
  501. +
  502. + /* Select DEVICEID register for C2 data register accesses */
  503. + c2port_write_ar(dev, C2PORT_DEVICEID);
  504. +
  505. + /* Read and return the device ID register */
  506. + ret = c2port_read_dr(dev, &data);
  507. + if (ret < 0)
  508. + return ret;
  509. +
  510. + return sprintf(buf, "%d\n", data);
  511. +}
  512. +
  513. +static ssize_t c2port_show_dev_id(struct device *dev,
  514. + struct device_attribute *attr, char *buf)
  515. +{
  516. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  517. + ssize_t ret;
  518. +
  519. + /* Check the device access status */
  520. + if (!c2dev->access)
  521. + return -EBUSY;
  522. +
  523. + mutex_lock(&c2dev->mutex);
  524. + ret = __c2port_show_dev_id(c2dev, buf);
  525. + mutex_unlock(&c2dev->mutex);
  526. +
  527. + if (ret < 0)
  528. + dev_err(dev, "cannot read from %s\n", c2dev->name);
  529. +
  530. + return ret;
  531. +}
  532. +static DEVICE_ATTR(dev_id, 0444, c2port_show_dev_id, NULL);
  533. +
  534. +static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
  535. +{
  536. + u8 data;
  537. + int ret;
  538. +
  539. + /* Select REVID register for C2 data register accesses */
  540. + c2port_write_ar(dev, C2PORT_REVID);
  541. +
  542. + /* Read and return the revision ID register */
  543. + ret = c2port_read_dr(dev, &data);
  544. + if (ret < 0)
  545. + return ret;
  546. +
  547. + return sprintf(buf, "%d\n", data);
  548. +}
  549. +
  550. +static ssize_t c2port_show_rev_id(struct device *dev,
  551. + struct device_attribute *attr, char *buf)
  552. +{
  553. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  554. + ssize_t ret;
  555. +
  556. + /* Check the device access status */
  557. + if (!c2dev->access)
  558. + return -EBUSY;
  559. +
  560. + mutex_lock(&c2dev->mutex);
  561. + ret = __c2port_show_rev_id(c2dev, buf);
  562. + mutex_unlock(&c2dev->mutex);
  563. +
  564. + if (ret < 0)
  565. + dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name);
  566. +
  567. + return ret;
  568. +}
  569. +static DEVICE_ATTR(rev_id, 0444, c2port_show_rev_id, NULL);
  570. +
  571. +static ssize_t c2port_show_flash_access(struct device *dev,
  572. + struct device_attribute *attr, char *buf)
  573. +{
  574. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  575. +
  576. + return sprintf(buf, "%d\n", c2dev->flash_access);
  577. +}
  578. +
  579. +static ssize_t __c2port_store_flash_access(struct c2port_device *dev,
  580. + int status)
  581. +{
  582. + int ret;
  583. +
  584. + /* Check the device access status */
  585. + if (!dev->access)
  586. + return -EBUSY;
  587. +
  588. + dev->flash_access = !!status;
  589. +
  590. + /* If flash_access is off we have nothing to do... */
  591. + if (dev->flash_access == 0)
  592. + return 0;
  593. +
  594. + /* Target the C2 flash programming control register for C2 data
  595. + * register access */
  596. + c2port_write_ar(dev, C2PORT_FPCTL);
  597. +
  598. + /* Write the first keycode to enable C2 Flash programming */
  599. + ret = c2port_write_dr(dev, 0x02);
  600. + if (ret < 0)
  601. + return ret;
  602. +
  603. + /* Write the second keycode to enable C2 Flash programming */
  604. + ret = c2port_write_dr(dev, 0x01);
  605. + if (ret < 0)
  606. + return ret;
  607. +
  608. + /* Delay for at least 20ms to ensure the target is ready for
  609. + * C2 flash programming */
  610. + mdelay(25);
  611. +
  612. + return 0;
  613. +}
  614. +
  615. +static ssize_t c2port_store_flash_access(struct device *dev,
  616. + struct device_attribute *attr,
  617. + const char *buf, size_t count)
  618. +{
  619. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  620. + int status;
  621. + ssize_t ret;
  622. +
  623. + ret = sscanf(buf, "%d", &status);
  624. + if (ret != 1)
  625. + return -EINVAL;
  626. +
  627. + mutex_lock(&c2dev->mutex);
  628. + ret = __c2port_store_flash_access(c2dev, status);
  629. + mutex_unlock(&c2dev->mutex);
  630. +
  631. + if (ret < 0) {
  632. + dev_err(c2dev->dev, "cannot enable %s flash programming\n",
  633. + c2dev->name);
  634. + return ret;
  635. + }
  636. +
  637. + return count;
  638. +}
  639. +static DEVICE_ATTR(flash_access, 0644, c2port_show_flash_access,
  640. + c2port_store_flash_access);
  641. +
  642. +static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
  643. +{
  644. + u8 status;
  645. + int ret;
  646. +
  647. + /* Target the C2 flash programming data register for C2 data register
  648. + * access.
  649. + */
  650. + c2port_write_ar(dev, C2PORT_FPDAT);
  651. +
  652. + /* Send device erase command */
  653. + c2port_write_dr(dev, C2PORT_DEVICE_ERASE);
  654. +
  655. + /* Wait for input acknowledge */
  656. + ret = c2port_poll_in_busy(dev);
  657. + if (ret < 0)
  658. + return ret;
  659. +
  660. + /* Should check status before starting FLASH access sequence */
  661. +
  662. + /* Wait for status information */
  663. + ret = c2port_poll_out_ready(dev);
  664. + if (ret < 0)
  665. + return ret;
  666. +
  667. + /* Read flash programming interface status */
  668. + ret = c2port_read_dr(dev, &status);
  669. + if (ret < 0)
  670. + return ret;
  671. + if (status != C2PORT_COMMAND_OK)
  672. + return -EBUSY;
  673. +
  674. + /* Send a three-byte arming sequence to enable the device erase.
  675. + * If the sequence is not received correctly, the command will be
  676. + * ignored.
  677. + * Sequence is: 0xde, 0xad, 0xa5.
  678. + */
  679. + c2port_write_dr(dev, 0xde);
  680. + ret = c2port_poll_in_busy(dev);
  681. + if (ret < 0)
  682. + return ret;
  683. + c2port_write_dr(dev, 0xad);
  684. + ret = c2port_poll_in_busy(dev);
  685. + if (ret < 0)
  686. + return ret;
  687. + c2port_write_dr(dev, 0xa5);
  688. + ret = c2port_poll_in_busy(dev);
  689. + if (ret < 0)
  690. + return ret;
  691. +
  692. + ret = c2port_poll_out_ready(dev);
  693. + if (ret < 0)
  694. + return ret;
  695. +
  696. + return 0;
  697. +}
  698. +
  699. +static ssize_t c2port_store_flash_erase(struct device *dev,
  700. + struct device_attribute *attr,
  701. + const char *buf, size_t count)
  702. +{
  703. + struct c2port_device *c2dev = dev_get_drvdata(dev);
  704. + int ret;
  705. +
  706. + /* Check the device and flash access status */
  707. + if (!c2dev->access || !c2dev->flash_access)
  708. + return -EBUSY;
  709. +
  710. + mutex_lock(&c2dev->mutex);
  711. + ret = __c2port_write_flash_erase(c2dev);
  712. + mutex_unlock(&c2dev->mutex);
  713. +
  714. + if (ret < 0) {
  715. + dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name);
  716. + return ret;
  717. + }
  718. +
  719. + return count;
  720. +}
  721. +static DEVICE_ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase);
  722. +
  723. +static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
  724. + char *buffer, loff_t offset, size_t count)
  725. +{
  726. + struct c2port_ops *ops = dev->ops;
  727. + u8 status, nread = 128;
  728. + int i, ret;
  729. +
  730. + /* Check for flash end */
  731. + if (offset >= ops->block_size * ops->blocks_num)
  732. + return 0;
  733. +
  734. + if (ops->block_size * ops->blocks_num - offset < nread)
  735. + nread = ops->block_size * ops->blocks_num - offset;
  736. + if (count < nread)
  737. + nread = count;
  738. + if (nread == 0)
  739. + return nread;
  740. +
  741. + /* Target the C2 flash programming data register for C2 data register
  742. + * access */
  743. + c2port_write_ar(dev, C2PORT_FPDAT);
  744. +
  745. + /* Send flash block read command */
  746. + c2port_write_dr(dev, C2PORT_BLOCK_READ);
  747. +
  748. + /* Wait for input acknowledge */
  749. + ret = c2port_poll_in_busy(dev);
  750. + if (ret < 0)
  751. + return ret;
  752. +
  753. + /* Should check status before starting FLASH access sequence */
  754. +
  755. + /* Wait for status information */
  756. + ret = c2port_poll_out_ready(dev);
  757. + if (ret < 0)
  758. + return ret;
  759. +
  760. + /* Read flash programming interface status */
  761. + ret = c2port_read_dr(dev, &status);
  762. + if (ret < 0)
  763. + return ret;
  764. + if (status != C2PORT_COMMAND_OK)
  765. + return -EBUSY;
  766. +
  767. + /* Send address high byte */
  768. + c2port_write_dr(dev, offset >> 8);
  769. + ret = c2port_poll_in_busy(dev);
  770. + if (ret < 0)
  771. + return ret;
  772. +
  773. + /* Send address low byte */
  774. + c2port_write_dr(dev, offset & 0x00ff);
  775. + ret = c2port_poll_in_busy(dev);
  776. + if (ret < 0)
  777. + return ret;
  778. +
  779. + /* Send address block size */
  780. + c2port_write_dr(dev, nread);
  781. + ret = c2port_poll_in_busy(dev);
  782. + if (ret < 0)
  783. + return ret;
  784. +
  785. + /* Should check status before reading FLASH block */
  786. +
  787. + /* Wait for status information */
  788. + ret = c2port_poll_out_ready(dev);
  789. + if (ret < 0)
  790. + return ret;
  791. +
  792. + /* Read flash programming interface status */
  793. + ret = c2port_read_dr(dev, &status);
  794. + if (ret < 0)
  795. + return ret;
  796. + if (status != C2PORT_COMMAND_OK)
  797. + return -EBUSY;
  798. +
  799. + /* Read flash block */
  800. + for (i = 0; i < nread; i++) {
  801. + ret = c2port_poll_out_ready(dev);
  802. + if (ret < 0)
  803. + return ret;
  804. +
  805. + ret = c2port_read_dr(dev, buffer+i);
  806. + if (ret < 0)
  807. + return ret;
  808. + }
  809. +
  810. + return nread;
  811. +}
  812. +
  813. +static ssize_t c2port_read_flash_data(struct file *filp, struct kobject *kobj,
  814. + struct bin_attribute *attr,
  815. + char *buffer, loff_t offset, size_t count)
  816. +{
  817. + struct c2port_device *c2dev =
  818. + dev_get_drvdata(container_of(kobj,
  819. + struct device, kobj));
  820. + ssize_t ret;
  821. +
  822. + /* Check the device and flash access status */
  823. + if (!c2dev->access || !c2dev->flash_access)
  824. + return -EBUSY;
  825. +
  826. + mutex_lock(&c2dev->mutex);
  827. + ret = __c2port_read_flash_data(c2dev, buffer, offset, count);
  828. + mutex_unlock(&c2dev->mutex);
  829. +
  830. + if (ret < 0)
  831. + dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name);
  832. +
  833. + return ret;
  834. +}
  835. +
  836. +static ssize_t __c2port_write_flash_data(struct c2port_device *dev,
  837. + char *buffer, loff_t offset, size_t count)
  838. +{
  839. + struct c2port_ops *ops = dev->ops;
  840. + u8 status, nwrite = 128;
  841. + int i, ret;
  842. +
  843. + if (nwrite > count)
  844. + nwrite = count;
  845. + if (ops->block_size * ops->blocks_num - offset < nwrite)
  846. + nwrite = ops->block_size * ops->blocks_num - offset;
  847. +
  848. + /* Check for flash end */
  849. + if (offset >= ops->block_size * ops->blocks_num)
  850. + return -EINVAL;
  851. +
  852. + /* Target the C2 flash programming data register for C2 data register
  853. + * access */
  854. + c2port_write_ar(dev, C2PORT_FPDAT);
  855. +
  856. + /* Send flash block write command */
  857. + c2port_write_dr(dev, C2PORT_BLOCK_WRITE);
  858. +
  859. + /* Wait for input acknowledge */
  860. + ret = c2port_poll_in_busy(dev);
  861. + if (ret < 0)
  862. + return ret;
  863. +
  864. + /* Should check status before starting FLASH access sequence */
  865. +
  866. + /* Wait for status information */
  867. + ret = c2port_poll_out_ready(dev);
  868. + if (ret < 0)
  869. + return ret;
  870. +
  871. + /* Read flash programming interface status */
  872. + ret = c2port_read_dr(dev, &status);
  873. + if (ret < 0)
  874. + return ret;
  875. + if (status != C2PORT_COMMAND_OK)
  876. + return -EBUSY;
  877. +
  878. + /* Send address high byte */
  879. + c2port_write_dr(dev, offset >> 8);
  880. + ret = c2port_poll_in_busy(dev);
  881. + if (ret < 0)
  882. + return ret;
  883. +
  884. + /* Send address low byte */
  885. + c2port_write_dr(dev, offset & 0x00ff);
  886. + ret = c2port_poll_in_busy(dev);
  887. + if (ret < 0)
  888. + return ret;
  889. +
  890. + /* Send address block size */
  891. + c2port_write_dr(dev, nwrite);
  892. + ret = c2port_poll_in_busy(dev);
  893. + if (ret < 0)
  894. + return ret;
  895. +
  896. + /* Should check status before writing FLASH block */
  897. +
  898. + /* Wait for status information */
  899. + ret = c2port_poll_out_ready(dev);
  900. + if (ret < 0)
  901. + return ret;
  902. +
  903. + /* Read flash programming interface status */
  904. + ret = c2port_read_dr(dev, &status);
  905. + if (ret < 0)
  906. + return ret;
  907. + if (status != C2PORT_COMMAND_OK)
  908. + return -EBUSY;
  909. +
  910. + /* Write flash block */
  911. + for (i = 0; i < nwrite; i++) {
  912. + ret = c2port_write_dr(dev, *(buffer+i));
  913. + if (ret < 0)
  914. + return ret;
  915. +
  916. + ret = c2port_poll_in_busy(dev);
  917. + if (ret < 0)
  918. + return ret;
  919. +
  920. + }
  921. +
  922. + /* Wait for last flash write to complete */
  923. + ret = c2port_poll_out_ready(dev);
  924. + if (ret < 0)
  925. + return ret;
  926. +
  927. + return nwrite;
  928. +}
  929. +
  930. +static ssize_t c2port_write_flash_data(struct file *filp, struct kobject *kobj,
  931. + struct bin_attribute *attr,
  932. + char *buffer, loff_t offset, size_t count)
  933. +{
  934. + struct c2port_device *c2dev =
  935. + dev_get_drvdata(container_of(kobj,
  936. + struct device, kobj));
  937. + int ret;
  938. +
  939. + /* Check the device access status */
  940. + if (!c2dev->access || !c2dev->flash_access)
  941. + return -EBUSY;
  942. +
  943. + mutex_lock(&c2dev->mutex);
  944. + ret = __c2port_write_flash_data(c2dev, buffer, offset, count);
  945. + mutex_unlock(&c2dev->mutex);
  946. +
  947. + if (ret < 0)
  948. + dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name);
  949. +
  950. + return ret;
  951. +}
  952. +/* size is computed at run-time */
  953. +static BIN_ATTR(flash_data, 0644, c2port_read_flash_data,
  954. + c2port_write_flash_data, 0);
  955. +
  956. +/*
  957. + * Class attributes
  958. + */
  959. +static struct attribute *c2port_attrs[] = {
  960. + &dev_attr_name.attr,
  961. + &dev_attr_flash_blocks_num.attr,
  962. + &dev_attr_flash_block_size.attr,
  963. + &dev_attr_flash_size.attr,
  964. + &dev_attr_access.attr,
  965. + &dev_attr_reset.attr,
  966. + &dev_attr_dev_id.attr,
  967. + &dev_attr_rev_id.attr,
  968. + &dev_attr_flash_access.attr,
  969. + &dev_attr_flash_erase.attr,
  970. + NULL,
  971. +};
  972. +
  973. +static struct bin_attribute *c2port_bin_attrs[] = {
  974. + &bin_attr_flash_data,
  975. + NULL,
  976. +};
  977. +
  978. +static const struct attribute_group c2port_group = {
  979. + .attrs = c2port_attrs,
  980. + .bin_attrs = c2port_bin_attrs,
  981. +};
  982. +
  983. +static const struct attribute_group *c2port_groups[] = {
  984. + &c2port_group,
  985. + NULL,
  986. +};
  987. +
  988. +/*
  989. + * Exported functions
  990. + */
  991. +
  992. +struct c2port_device *c2port_device_register(char *name,
  993. + struct c2port_ops *ops, void *devdata)
  994. +{
  995. + struct c2port_device *c2dev;
  996. + int ret;
  997. +
  998. + if (unlikely(!ops) || unlikely(!ops->access) || \
  999. + unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
  1000. + unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set))
  1001. + return ERR_PTR(-EINVAL);
  1002. +
  1003. + c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL);
  1004. + kmemcheck_annotate_bitfield(c2dev, flags);
  1005. + if (unlikely(!c2dev))
  1006. + return ERR_PTR(-ENOMEM);
  1007. +
  1008. + idr_preload(GFP_KERNEL);
  1009. + spin_lock_irq(&c2port_idr_lock);
  1010. + ret = idr_alloc(&c2port_idr, c2dev, 0, 0, GFP_NOWAIT);
  1011. + spin_unlock_irq(&c2port_idr_lock);
  1012. + idr_preload_end();
  1013. +
  1014. + if (ret < 0)
  1015. + goto error_idr_alloc;
  1016. + c2dev->id = ret;
  1017. +
  1018. + bin_attr_flash_data.size = ops->blocks_num * ops->block_size;
  1019. +
  1020. + c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
  1021. + "c2port%d", c2dev->id);
  1022. + if (unlikely(IS_ERR(c2dev->dev))) {
  1023. + ret = PTR_ERR(c2dev->dev);
  1024. + goto error_device_create;
  1025. + }
  1026. + dev_set_drvdata(c2dev->dev, c2dev);
  1027. +
  1028. + strncpy(c2dev->name, name, C2PORT_NAME_LEN);
  1029. + c2dev->ops = ops;
  1030. + mutex_init(&c2dev->mutex);
  1031. +
  1032. + /* By default C2 port access is off */
  1033. + c2dev->access = c2dev->flash_access = 0;
  1034. + ops->access(c2dev, 0);
  1035. +
  1036. + dev_info(c2dev->dev, "C2 port %s added\n", name);
  1037. + dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes "
  1038. + "(%d bytes total)\n",
  1039. + name, ops->blocks_num, ops->block_size,
  1040. + ops->blocks_num * ops->block_size);
  1041. +
  1042. + return c2dev;
  1043. +
  1044. +error_device_create:
  1045. + spin_lock_irq(&c2port_idr_lock);
  1046. + idr_remove(&c2port_idr, c2dev->id);
  1047. + spin_unlock_irq(&c2port_idr_lock);
  1048. +
  1049. +error_idr_alloc:
  1050. + kfree(c2dev);
  1051. +
  1052. + return ERR_PTR(ret);
  1053. +}
  1054. +EXPORT_SYMBOL(c2port_device_register);
  1055. +
  1056. +void c2port_device_unregister(struct c2port_device *c2dev)
  1057. +{
  1058. + if (!c2dev)
  1059. + return;
  1060. +
  1061. + dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
  1062. +
  1063. + spin_lock_irq(&c2port_idr_lock);
  1064. + idr_remove(&c2port_idr, c2dev->id);
  1065. + spin_unlock_irq(&c2port_idr_lock);
  1066. +
  1067. + device_destroy(c2port_class, c2dev->id);
  1068. +
  1069. + kfree(c2dev);
  1070. +}
  1071. +EXPORT_SYMBOL(c2port_device_unregister);
  1072. +
  1073. +/*
  1074. + * Module stuff
  1075. + */
  1076. +
  1077. +static int __init c2port_init(void)
  1078. +{
  1079. + printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION
  1080. + " - (C) 2007 Rodolfo Giometti\n");
  1081. +
  1082. + c2port_class = class_create(THIS_MODULE, "c2port");
  1083. + if (IS_ERR(c2port_class)) {
  1084. + printk(KERN_ERR "c2port: failed to allocate class\n");
  1085. + return PTR_ERR(c2port_class);
  1086. + }
  1087. + c2port_class->dev_groups = c2port_groups;
  1088. +
  1089. + return 0;
  1090. +}
  1091. +
  1092. +static void __exit c2port_exit(void)
  1093. +{
  1094. + class_destroy(c2port_class);
  1095. +}
  1096. +
  1097. +module_init(c2port_init);
  1098. +module_exit(c2port_exit);
  1099. +
  1100. +MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
  1101. +MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION);
  1102. +MODULE_LICENSE("GPL");
  1103. diff --git a/drivers/misc/c2port/c2port-duramar2150.c b/drivers/misc/c2port/c2port-duramar2150.c
  1104. deleted file mode 100644
  1105. index 5484301..0000000
  1106. --- a/drivers/misc/c2port/c2port-duramar2150.c
  1107. +++ /dev/null
  1108. @@ -1,159 +0,0 @@
  1109. -/*
  1110. - * Silicon Labs C2 port Linux support for Eurotech Duramar 2150
  1111. - *
  1112. - * Copyright (c) 2008 Rodolfo Giometti <giometti@linux.it>
  1113. - * Copyright (c) 2008 Eurotech S.p.A. <info@eurotech.it>
  1114. - *
  1115. - * This program is free software; you can redistribute it and/or modify it
  1116. - * under the terms of the GNU General Public License version 2 as published by
  1117. - * the Free Software Foundation
  1118. - */
  1119. -
  1120. -#include <linux/errno.h>
  1121. -#include <linux/init.h>
  1122. -#include <linux/kernel.h>
  1123. -#include <linux/module.h>
  1124. -#include <linux/delay.h>
  1125. -#include <linux/io.h>
  1126. -#include <linux/ioport.h>
  1127. -#include <linux/c2port.h>
  1128. -
  1129. -#define DATA_PORT 0x325
  1130. -#define DIR_PORT 0x326
  1131. -#define C2D (1 << 0)
  1132. -#define C2CK (1 << 1)
  1133. -
  1134. -static DEFINE_MUTEX(update_lock);
  1135. -
  1136. -/*
  1137. - * C2 port operations
  1138. - */
  1139. -
  1140. -static void duramar2150_c2port_access(struct c2port_device *dev, int status)
  1141. -{
  1142. - u8 v;
  1143. -
  1144. - mutex_lock(&update_lock);
  1145. -
  1146. - v = inb(DIR_PORT);
  1147. -
  1148. - /* 0 = input, 1 = output */
  1149. - if (status)
  1150. - outb(v | (C2D | C2CK), DIR_PORT);
  1151. - else
  1152. - /* When access is "off" is important that both lines are set
  1153. - * as inputs or hi-impedance */
  1154. - outb(v & ~(C2D | C2CK), DIR_PORT);
  1155. -
  1156. - mutex_unlock(&update_lock);
  1157. -}
  1158. -
  1159. -static void duramar2150_c2port_c2d_dir(struct c2port_device *dev, int dir)
  1160. -{
  1161. - u8 v;
  1162. -
  1163. - mutex_lock(&update_lock);
  1164. -
  1165. - v = inb(DIR_PORT);
  1166. -
  1167. - if (dir)
  1168. - outb(v & ~C2D, DIR_PORT);
  1169. - else
  1170. - outb(v | C2D, DIR_PORT);
  1171. -
  1172. - mutex_unlock(&update_lock);
  1173. -}
  1174. -
  1175. -static int duramar2150_c2port_c2d_get(struct c2port_device *dev)
  1176. -{
  1177. - return inb(DATA_PORT) & C2D;
  1178. -}
  1179. -
  1180. -static void duramar2150_c2port_c2d_set(struct c2port_device *dev, int status)
  1181. -{
  1182. - u8 v;
  1183. -
  1184. - mutex_lock(&update_lock);
  1185. -
  1186. - v = inb(DATA_PORT);
  1187. -
  1188. - if (status)
  1189. - outb(v | C2D, DATA_PORT);
  1190. - else
  1191. - outb(v & ~C2D, DATA_PORT);
  1192. -
  1193. - mutex_unlock(&update_lock);
  1194. -}
  1195. -
  1196. -static void duramar2150_c2port_c2ck_set(struct c2port_device *dev, int status)
  1197. -{
  1198. - u8 v;
  1199. -
  1200. - mutex_lock(&update_lock);
  1201. -
  1202. - v = inb(DATA_PORT);
  1203. -
  1204. - if (status)
  1205. - outb(v | C2CK, DATA_PORT);
  1206. - else
  1207. - outb(v & ~C2CK, DATA_PORT);
  1208. -
  1209. - mutex_unlock(&update_lock);
  1210. -}
  1211. -
  1212. -static struct c2port_ops duramar2150_c2port_ops = {
  1213. - .block_size = 512, /* bytes */
  1214. - .blocks_num = 30, /* total flash size: 15360 bytes */
  1215. -
  1216. - .access = duramar2150_c2port_access,
  1217. - .c2d_dir = duramar2150_c2port_c2d_dir,
  1218. - .c2d_get = duramar2150_c2port_c2d_get,
  1219. - .c2d_set = duramar2150_c2port_c2d_set,
  1220. - .c2ck_set = duramar2150_c2port_c2ck_set,
  1221. -};
  1222. -
  1223. -static struct c2port_device *duramar2150_c2port_dev;
  1224. -
  1225. -/*
  1226. - * Module stuff
  1227. - */
  1228. -
  1229. -static int __init duramar2150_c2port_init(void)
  1230. -{
  1231. - struct resource *res;
  1232. - int ret = 0;
  1233. -
  1234. - res = request_region(0x325, 2, "c2port");
  1235. - if (!res)
  1236. - return -EBUSY;
  1237. -
  1238. - duramar2150_c2port_dev = c2port_device_register("uc",
  1239. - &duramar2150_c2port_ops, NULL);
  1240. - if (!duramar2150_c2port_dev) {
  1241. - ret = -ENODEV;
  1242. - goto free_region;
  1243. - }
  1244. -
  1245. - return 0;
  1246. -
  1247. -free_region:
  1248. - release_region(0x325, 2);
  1249. - return ret;
  1250. -}
  1251. -
  1252. -static void __exit duramar2150_c2port_exit(void)
  1253. -{
  1254. - /* Setup the GPIOs as input by default (access = 0) */
  1255. - duramar2150_c2port_access(duramar2150_c2port_dev, 0);
  1256. -
  1257. - c2port_device_unregister(duramar2150_c2port_dev);
  1258. -
  1259. - release_region(0x325, 2);
  1260. -}
  1261. -
  1262. -module_init(duramar2150_c2port_init);
  1263. -module_exit(duramar2150_c2port_exit);
  1264. -
  1265. -MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
  1266. -MODULE_DESCRIPTION("Silicon Labs C2 port Linux support for Duramar 2150");
  1267. -MODULE_LICENSE("GPL");
  1268. diff --git a/drivers/misc/c2port/c2port-gpio.c b/drivers/misc/c2port/c2port-gpio.c
  1269. new file mode 100644
  1270. index 0000000..4928ee5
  1271. --- /dev/null
  1272. +++ b/drivers/misc/c2port/c2port-gpio.c
  1273. @@ -0,0 +1,125 @@
  1274. +/*
  1275. + * Silicon Labs C2 port Linux support for GPIO
  1276. + *
  1277. + * Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it>
  1278. + * Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it>
  1279. + * Copyright (c) 2014 Gerhard Bertelsmann <info@gerhard-bertelsmann.de>
  1280. + *
  1281. + * This program is free software; you can redistribute it and/or modify it
  1282. + * under the terms of the GNU General Public License version 2 as published by
  1283. + * the Free Software Foundation
  1284. + */
  1285. +
  1286. +#include <linux/errno.h>
  1287. +#include <linux/init.h>
  1288. +#include <linux/kernel.h>
  1289. +#include <linux/module.h>
  1290. +#include <linux/gpio.h>
  1291. +#include <linux/delay.h>
  1292. +
  1293. +#include <linux/c2port.h>
  1294. +
  1295. +static int c2ck = 1;
  1296. +static int c2d = 0;
  1297. +
  1298. +module_param(c2ck, int, S_IRUSR);
  1299. +MODULE_PARM_DESC(c2ck, "C2CK pin");
  1300. +module_param(c2d, int, S_IRUSR);
  1301. +MODULE_PARM_DESC(c2d, "C2D pin");
  1302. +
  1303. +/* --- C2 port operations --------------------------------------------------- */
  1304. +
  1305. +static void gpio_c2port_access(struct c2port_device *dev, int status)
  1306. +{
  1307. + if (status) {
  1308. + gpio_direction_output(c2ck, 1);
  1309. + gpio_direction_output(c2d, 1);
  1310. + } else {
  1311. + /* When access is "off" is important that both lines are set
  1312. + * as inputs or hi-impedence */
  1313. + gpio_direction_input(c2ck);
  1314. + gpio_direction_input(c2d);
  1315. + }
  1316. +}
  1317. +
  1318. +static void gpio_c2port_c2d_dir(struct c2port_device *dev, int dir)
  1319. +{
  1320. + if (dir)
  1321. + gpio_direction_input(c2d);
  1322. + else
  1323. + gpio_direction_output(c2d, gpio_get_value(c2d));
  1324. +}
  1325. +
  1326. +static int gpio_c2port_c2d_get(struct c2port_device *dev)
  1327. +{
  1328. + return gpio_get_value(c2d);
  1329. +}
  1330. +
  1331. +static void gpio_c2port_c2d_set(struct c2port_device *dev, int status)
  1332. +{
  1333. + gpio_set_value(c2d, status);
  1334. +}
  1335. +
  1336. +static void gpio_c2port_c2ck_set(struct c2port_device *dev, int status)
  1337. +{
  1338. + gpio_set_value(c2ck, status);
  1339. +}
  1340. +
  1341. +static struct c2port_ops gpio_c2port_ops = {
  1342. + block_size :512, /* bytes */
  1343. + blocks_num :30, /* total flash size: 15360 bytes */
  1344. + access :gpio_c2port_access,
  1345. + c2d_dir :gpio_c2port_c2d_dir,
  1346. + c2d_get :gpio_c2port_c2d_get,
  1347. + c2d_set :gpio_c2port_c2d_set,
  1348. + c2ck_set :gpio_c2port_c2ck_set,
  1349. +};
  1350. +
  1351. +static struct c2port_device *gpio_c2port_dev;
  1352. +
  1353. +/* --- Module stuff --------------------------------------------------------- */
  1354. +
  1355. +static int __init gpio_c2port_init(void)
  1356. +{
  1357. + int ret;
  1358. +
  1359. + ret = gpio_request(c2ck, "c2port clock");
  1360. + if (ret)
  1361. + goto exit;
  1362. + gpio_direction_input(c2ck);
  1363. +
  1364. + ret = gpio_request(c2d, "c2port data");
  1365. + if (ret)
  1366. + goto free_gpio;
  1367. + gpio_direction_input(c2d);
  1368. +
  1369. + gpio_c2port_dev = c2port_device_register("uc", &gpio_c2port_ops, NULL);
  1370. + if (!gpio_c2port_dev)
  1371. + return -ENODEV;
  1372. +
  1373. + return 0;
  1374. +
  1375. +free_gpio:
  1376. + gpio_free(c2ck);
  1377. +exit:
  1378. + return ret;
  1379. +}
  1380. +
  1381. +static void __exit gpio_c2port_exit(void)
  1382. +{
  1383. + /* Setup the GPIOs as input by default (access = 0) */
  1384. + gpio_c2port_access(gpio_c2port_dev, 0);
  1385. +
  1386. + c2port_device_unregister(gpio_c2port_dev);
  1387. +
  1388. + gpio_free(c2ck);
  1389. + gpio_free(c2d);
  1390. +}
  1391. +
  1392. +module_init(gpio_c2port_init);
  1393. +module_exit(gpio_c2port_exit);
  1394. +
  1395. +MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
  1396. +MODULE_AUTHOR("Gerhard Bertelsmann <info@gerhard-bertelsmann.de>");
  1397. +MODULE_DESCRIPTION("Silicon Labs C2 port Linux support for GPIO");
  1398. +MODULE_LICENSE("GPL");
  1399. diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c
  1400. deleted file mode 100644
  1401. index 464419b..0000000
  1402. --- a/drivers/misc/c2port/core.c
  1403. +++ /dev/null
  1404. @@ -1,1009 +0,0 @@
  1405. -/*
  1406. - * Silicon Labs C2 port core Linux support
  1407. - *
  1408. - * Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it>
  1409. - * Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it>
  1410. - *
  1411. - * This program is free software; you can redistribute it and/or modify it
  1412. - * under the terms of the GNU General Public License version 2 as published by
  1413. - * the Free Software Foundation
  1414. - */
  1415. -
  1416. -#include <linux/module.h>
  1417. -#include <linux/init.h>
  1418. -#include <linux/device.h>
  1419. -#include <linux/errno.h>
  1420. -#include <linux/err.h>
  1421. -#include <linux/kernel.h>
  1422. -#include <linux/kmemcheck.h>
  1423. -#include <linux/ctype.h>
  1424. -#include <linux/delay.h>
  1425. -#include <linux/idr.h>
  1426. -#include <linux/sched.h>
  1427. -#include <linux/slab.h>
  1428. -
  1429. -#include <linux/c2port.h>
  1430. -
  1431. -#define DRIVER_NAME "c2port"
  1432. -#define DRIVER_VERSION "0.51.0"
  1433. -
  1434. -static DEFINE_SPINLOCK(c2port_idr_lock);
  1435. -static DEFINE_IDR(c2port_idr);
  1436. -
  1437. -/*
  1438. - * Local variables
  1439. - */
  1440. -
  1441. -static struct class *c2port_class;
  1442. -
  1443. -/*
  1444. - * C2 registers & commands defines
  1445. - */
  1446. -
  1447. -/* C2 registers */
  1448. -#define C2PORT_DEVICEID 0x00
  1449. -#define C2PORT_REVID 0x01
  1450. -#define C2PORT_FPCTL 0x02
  1451. -#define C2PORT_FPDAT 0xB4
  1452. -
  1453. -/* C2 interface commands */
  1454. -#define C2PORT_GET_VERSION 0x01
  1455. -#define C2PORT_DEVICE_ERASE 0x03
  1456. -#define C2PORT_BLOCK_READ 0x06
  1457. -#define C2PORT_BLOCK_WRITE 0x07
  1458. -#define C2PORT_PAGE_ERASE 0x08
  1459. -
  1460. -/* C2 status return codes */
  1461. -#define C2PORT_INVALID_COMMAND 0x00
  1462. -#define C2PORT_COMMAND_FAILED 0x02
  1463. -#define C2PORT_COMMAND_OK 0x0d
  1464. -
  1465. -/*
  1466. - * C2 port low level signal managements
  1467. - */
  1468. -
  1469. -static void c2port_reset(struct c2port_device *dev)
  1470. -{
  1471. - struct c2port_ops *ops = dev->ops;
  1472. -
  1473. - /* To reset the device we have to keep clock line low for at least
  1474. - * 20us.
  1475. - */
  1476. - local_irq_disable();
  1477. - ops->c2ck_set(dev, 0);
  1478. - udelay(25);
  1479. - ops->c2ck_set(dev, 1);
  1480. - local_irq_enable();
  1481. -
  1482. - udelay(1);
  1483. -}
  1484. -
  1485. -static void c2port_strobe_ck(struct c2port_device *dev)
  1486. -{
  1487. - struct c2port_ops *ops = dev->ops;
  1488. -
  1489. - /* During hi-low-hi transition we disable local IRQs to avoid
  1490. - * interructions since C2 port specification says that it must be
  1491. - * shorter than 5us, otherwise the microcontroller may consider
  1492. - * it as a reset signal!
  1493. - */
  1494. - local_irq_disable();
  1495. - ops->c2ck_set(dev, 0);
  1496. - udelay(1);
  1497. - ops->c2ck_set(dev, 1);
  1498. - local_irq_enable();
  1499. -
  1500. - udelay(1);
  1501. -}
  1502. -
  1503. -/*
  1504. - * C2 port basic functions
  1505. - */
  1506. -
  1507. -static void c2port_write_ar(struct c2port_device *dev, u8 addr)
  1508. -{
  1509. - struct c2port_ops *ops = dev->ops;
  1510. - int i;
  1511. -
  1512. - /* START field */
  1513. - c2port_strobe_ck(dev);
  1514. -
  1515. - /* INS field (11b, LSB first) */
  1516. - ops->c2d_dir(dev, 0);
  1517. - ops->c2d_set(dev, 1);
  1518. - c2port_strobe_ck(dev);
  1519. - ops->c2d_set(dev, 1);
  1520. - c2port_strobe_ck(dev);
  1521. -
  1522. - /* ADDRESS field */
  1523. - for (i = 0; i < 8; i++) {
  1524. - ops->c2d_set(dev, addr & 0x01);
  1525. - c2port_strobe_ck(dev);
  1526. -
  1527. - addr >>= 1;
  1528. - }
  1529. -
  1530. - /* STOP field */
  1531. - ops->c2d_dir(dev, 1);
  1532. - c2port_strobe_ck(dev);
  1533. -}
  1534. -
  1535. -static int c2port_read_ar(struct c2port_device *dev, u8 *addr)
  1536. -{
  1537. - struct c2port_ops *ops = dev->ops;
  1538. - int i;
  1539. -
  1540. - /* START field */
  1541. - c2port_strobe_ck(dev);
  1542. -
  1543. - /* INS field (10b, LSB first) */
  1544. - ops->c2d_dir(dev, 0);
  1545. - ops->c2d_set(dev, 0);
  1546. - c2port_strobe_ck(dev);
  1547. - ops->c2d_set(dev, 1);
  1548. - c2port_strobe_ck(dev);
  1549. -
  1550. - /* ADDRESS field */
  1551. - ops->c2d_dir(dev, 1);
  1552. - *addr = 0;
  1553. - for (i = 0; i < 8; i++) {
  1554. - *addr >>= 1; /* shift in 8-bit ADDRESS field LSB first */
  1555. -
  1556. - c2port_strobe_ck(dev);
  1557. - if (ops->c2d_get(dev))
  1558. - *addr |= 0x80;
  1559. - }
  1560. -
  1561. - /* STOP field */
  1562. - c2port_strobe_ck(dev);
  1563. -
  1564. - return 0;
  1565. -}
  1566. -
  1567. -static int c2port_write_dr(struct c2port_device *dev, u8 data)
  1568. -{
  1569. - struct c2port_ops *ops = dev->ops;
  1570. - int timeout, i;
  1571. -
  1572. - /* START field */
  1573. - c2port_strobe_ck(dev);
  1574. -
  1575. - /* INS field (01b, LSB first) */
  1576. - ops->c2d_dir(dev, 0);
  1577. - ops->c2d_set(dev, 1);
  1578. - c2port_strobe_ck(dev);
  1579. - ops->c2d_set(dev, 0);
  1580. - c2port_strobe_ck(dev);
  1581. -
  1582. - /* LENGTH field (00b, LSB first -> 1 byte) */
  1583. - ops->c2d_set(dev, 0);
  1584. - c2port_strobe_ck(dev);
  1585. - ops->c2d_set(dev, 0);
  1586. - c2port_strobe_ck(dev);
  1587. -
  1588. - /* DATA field */
  1589. - for (i = 0; i < 8; i++) {
  1590. - ops->c2d_set(dev, data & 0x01);
  1591. - c2port_strobe_ck(dev);
  1592. -
  1593. - data >>= 1;
  1594. - }
  1595. -
  1596. - /* WAIT field */
  1597. - ops->c2d_dir(dev, 1);
  1598. - timeout = 20;
  1599. - do {
  1600. - c2port_strobe_ck(dev);
  1601. - if (ops->c2d_get(dev))
  1602. - break;
  1603. -
  1604. - udelay(1);
  1605. - } while (--timeout > 0);
  1606. - if (timeout == 0)
  1607. - return -EIO;
  1608. -
  1609. - /* STOP field */
  1610. - c2port_strobe_ck(dev);
  1611. -
  1612. - return 0;
  1613. -}
  1614. -
  1615. -static int c2port_read_dr(struct c2port_device *dev, u8 *data)
  1616. -{
  1617. - struct c2port_ops *ops = dev->ops;
  1618. - int timeout, i;
  1619. -
  1620. - /* START field */
  1621. - c2port_strobe_ck(dev);
  1622. -
  1623. - /* INS field (00b, LSB first) */
  1624. - ops->c2d_dir(dev, 0);
  1625. - ops->c2d_set(dev, 0);
  1626. - c2port_strobe_ck(dev);
  1627. - ops->c2d_set(dev, 0);
  1628. - c2port_strobe_ck(dev);
  1629. -
  1630. - /* LENGTH field (00b, LSB first -> 1 byte) */
  1631. - ops->c2d_set(dev, 0);
  1632. - c2port_strobe_ck(dev);
  1633. - ops->c2d_set(dev, 0);
  1634. - c2port_strobe_ck(dev);
  1635. -
  1636. - /* WAIT field */
  1637. - ops->c2d_dir(dev, 1);
  1638. - timeout = 20;
  1639. - do {
  1640. - c2port_strobe_ck(dev);
  1641. - if (ops->c2d_get(dev))
  1642. - break;
  1643. -
  1644. - udelay(1);
  1645. - } while (--timeout > 0);
  1646. - if (timeout == 0)
  1647. - return -EIO;
  1648. -
  1649. - /* DATA field */
  1650. - *data = 0;
  1651. - for (i = 0; i < 8; i++) {
  1652. - *data >>= 1; /* shift in 8-bit DATA field LSB first */
  1653. -
  1654. - c2port_strobe_ck(dev);
  1655. - if (ops->c2d_get(dev))
  1656. - *data |= 0x80;
  1657. - }
  1658. -
  1659. - /* STOP field */
  1660. - c2port_strobe_ck(dev);
  1661. -
  1662. - return 0;
  1663. -}
  1664. -
  1665. -static int c2port_poll_in_busy(struct c2port_device *dev)
  1666. -{
  1667. - u8 addr;
  1668. - int ret, timeout = 20;
  1669. -
  1670. - do {
  1671. - ret = (c2port_read_ar(dev, &addr));
  1672. - if (ret < 0)
  1673. - return -EIO;
  1674. -
  1675. - if (!(addr & 0x02))
  1676. - break;
  1677. -
  1678. - udelay(1);
  1679. - } while (--timeout > 0);
  1680. - if (timeout == 0)
  1681. - return -EIO;
  1682. -
  1683. - return 0;
  1684. -}
  1685. -
  1686. -static int c2port_poll_out_ready(struct c2port_device *dev)
  1687. -{
  1688. - u8 addr;
  1689. - int ret, timeout = 10000; /* erase flash needs long time... */
  1690. -
  1691. - do {
  1692. - ret = (c2port_read_ar(dev, &addr));
  1693. - if (ret < 0)
  1694. - return -EIO;
  1695. -
  1696. - if (addr & 0x01)
  1697. - break;
  1698. -
  1699. - udelay(1);
  1700. - } while (--timeout > 0);
  1701. - if (timeout == 0)
  1702. - return -EIO;
  1703. -
  1704. - return 0;
  1705. -}
  1706. -
  1707. -/*
  1708. - * sysfs methods
  1709. - */
  1710. -
  1711. -static ssize_t c2port_show_name(struct device *dev,
  1712. - struct device_attribute *attr, char *buf)
  1713. -{
  1714. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1715. -
  1716. - return sprintf(buf, "%s\n", c2dev->name);
  1717. -}
  1718. -static DEVICE_ATTR(name, 0444, c2port_show_name, NULL);
  1719. -
  1720. -static ssize_t c2port_show_flash_blocks_num(struct device *dev,
  1721. - struct device_attribute *attr, char *buf)
  1722. -{
  1723. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1724. - struct c2port_ops *ops = c2dev->ops;
  1725. -
  1726. - return sprintf(buf, "%d\n", ops->blocks_num);
  1727. -}
  1728. -static DEVICE_ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL);
  1729. -
  1730. -static ssize_t c2port_show_flash_block_size(struct device *dev,
  1731. - struct device_attribute *attr, char *buf)
  1732. -{
  1733. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1734. - struct c2port_ops *ops = c2dev->ops;
  1735. -
  1736. - return sprintf(buf, "%d\n", ops->block_size);
  1737. -}
  1738. -static DEVICE_ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL);
  1739. -
  1740. -static ssize_t c2port_show_flash_size(struct device *dev,
  1741. - struct device_attribute *attr, char *buf)
  1742. -{
  1743. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1744. - struct c2port_ops *ops = c2dev->ops;
  1745. -
  1746. - return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
  1747. -}
  1748. -static DEVICE_ATTR(flash_size, 0444, c2port_show_flash_size, NULL);
  1749. -
  1750. -static ssize_t access_show(struct device *dev, struct device_attribute *attr,
  1751. - char *buf)
  1752. -{
  1753. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1754. -
  1755. - return sprintf(buf, "%d\n", c2dev->access);
  1756. -}
  1757. -
  1758. -static ssize_t access_store(struct device *dev, struct device_attribute *attr,
  1759. - const char *buf, size_t count)
  1760. -{
  1761. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1762. - struct c2port_ops *ops = c2dev->ops;
  1763. - int status, ret;
  1764. -
  1765. - ret = sscanf(buf, "%d", &status);
  1766. - if (ret != 1)
  1767. - return -EINVAL;
  1768. -
  1769. - mutex_lock(&c2dev->mutex);
  1770. -
  1771. - c2dev->access = !!status;
  1772. -
  1773. - /* If access is "on" clock should be HIGH _before_ setting the line
  1774. - * as output and data line should be set as INPUT anyway */
  1775. - if (c2dev->access)
  1776. - ops->c2ck_set(c2dev, 1);
  1777. - ops->access(c2dev, c2dev->access);
  1778. - if (c2dev->access)
  1779. - ops->c2d_dir(c2dev, 1);
  1780. -
  1781. - mutex_unlock(&c2dev->mutex);
  1782. -
  1783. - return count;
  1784. -}
  1785. -static DEVICE_ATTR_RW(access);
  1786. -
  1787. -static ssize_t c2port_store_reset(struct device *dev,
  1788. - struct device_attribute *attr,
  1789. - const char *buf, size_t count)
  1790. -{
  1791. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1792. -
  1793. - /* Check the device access status */
  1794. - if (!c2dev->access)
  1795. - return -EBUSY;
  1796. -
  1797. - mutex_lock(&c2dev->mutex);
  1798. -
  1799. - c2port_reset(c2dev);
  1800. - c2dev->flash_access = 0;
  1801. -
  1802. - mutex_unlock(&c2dev->mutex);
  1803. -
  1804. - return count;
  1805. -}
  1806. -static DEVICE_ATTR(reset, 0200, NULL, c2port_store_reset);
  1807. -
  1808. -static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
  1809. -{
  1810. - u8 data;
  1811. - int ret;
  1812. -
  1813. - /* Select DEVICEID register for C2 data register accesses */
  1814. - c2port_write_ar(dev, C2PORT_DEVICEID);
  1815. -
  1816. - /* Read and return the device ID register */
  1817. - ret = c2port_read_dr(dev, &data);
  1818. - if (ret < 0)
  1819. - return ret;
  1820. -
  1821. - return sprintf(buf, "%d\n", data);
  1822. -}
  1823. -
  1824. -static ssize_t c2port_show_dev_id(struct device *dev,
  1825. - struct device_attribute *attr, char *buf)
  1826. -{
  1827. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1828. - ssize_t ret;
  1829. -
  1830. - /* Check the device access status */
  1831. - if (!c2dev->access)
  1832. - return -EBUSY;
  1833. -
  1834. - mutex_lock(&c2dev->mutex);
  1835. - ret = __c2port_show_dev_id(c2dev, buf);
  1836. - mutex_unlock(&c2dev->mutex);
  1837. -
  1838. - if (ret < 0)
  1839. - dev_err(dev, "cannot read from %s\n", c2dev->name);
  1840. -
  1841. - return ret;
  1842. -}
  1843. -static DEVICE_ATTR(dev_id, 0444, c2port_show_dev_id, NULL);
  1844. -
  1845. -static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
  1846. -{
  1847. - u8 data;
  1848. - int ret;
  1849. -
  1850. - /* Select REVID register for C2 data register accesses */
  1851. - c2port_write_ar(dev, C2PORT_REVID);
  1852. -
  1853. - /* Read and return the revision ID register */
  1854. - ret = c2port_read_dr(dev, &data);
  1855. - if (ret < 0)
  1856. - return ret;
  1857. -
  1858. - return sprintf(buf, "%d\n", data);
  1859. -}
  1860. -
  1861. -static ssize_t c2port_show_rev_id(struct device *dev,
  1862. - struct device_attribute *attr, char *buf)
  1863. -{
  1864. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1865. - ssize_t ret;
  1866. -
  1867. - /* Check the device access status */
  1868. - if (!c2dev->access)
  1869. - return -EBUSY;
  1870. -
  1871. - mutex_lock(&c2dev->mutex);
  1872. - ret = __c2port_show_rev_id(c2dev, buf);
  1873. - mutex_unlock(&c2dev->mutex);
  1874. -
  1875. - if (ret < 0)
  1876. - dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name);
  1877. -
  1878. - return ret;
  1879. -}
  1880. -static DEVICE_ATTR(rev_id, 0444, c2port_show_rev_id, NULL);
  1881. -
  1882. -static ssize_t c2port_show_flash_access(struct device *dev,
  1883. - struct device_attribute *attr, char *buf)
  1884. -{
  1885. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1886. -
  1887. - return sprintf(buf, "%d\n", c2dev->flash_access);
  1888. -}
  1889. -
  1890. -static ssize_t __c2port_store_flash_access(struct c2port_device *dev,
  1891. - int status)
  1892. -{
  1893. - int ret;
  1894. -
  1895. - /* Check the device access status */
  1896. - if (!dev->access)
  1897. - return -EBUSY;
  1898. -
  1899. - dev->flash_access = !!status;
  1900. -
  1901. - /* If flash_access is off we have nothing to do... */
  1902. - if (dev->flash_access == 0)
  1903. - return 0;
  1904. -
  1905. - /* Target the C2 flash programming control register for C2 data
  1906. - * register access */
  1907. - c2port_write_ar(dev, C2PORT_FPCTL);
  1908. -
  1909. - /* Write the first keycode to enable C2 Flash programming */
  1910. - ret = c2port_write_dr(dev, 0x02);
  1911. - if (ret < 0)
  1912. - return ret;
  1913. -
  1914. - /* Write the second keycode to enable C2 Flash programming */
  1915. - ret = c2port_write_dr(dev, 0x01);
  1916. - if (ret < 0)
  1917. - return ret;
  1918. -
  1919. - /* Delay for at least 20ms to ensure the target is ready for
  1920. - * C2 flash programming */
  1921. - mdelay(25);
  1922. -
  1923. - return 0;
  1924. -}
  1925. -
  1926. -static ssize_t c2port_store_flash_access(struct device *dev,
  1927. - struct device_attribute *attr,
  1928. - const char *buf, size_t count)
  1929. -{
  1930. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  1931. - int status;
  1932. - ssize_t ret;
  1933. -
  1934. - ret = sscanf(buf, "%d", &status);
  1935. - if (ret != 1)
  1936. - return -EINVAL;
  1937. -
  1938. - mutex_lock(&c2dev->mutex);
  1939. - ret = __c2port_store_flash_access(c2dev, status);
  1940. - mutex_unlock(&c2dev->mutex);
  1941. -
  1942. - if (ret < 0) {
  1943. - dev_err(c2dev->dev, "cannot enable %s flash programming\n",
  1944. - c2dev->name);
  1945. - return ret;
  1946. - }
  1947. -
  1948. - return count;
  1949. -}
  1950. -static DEVICE_ATTR(flash_access, 0644, c2port_show_flash_access,
  1951. - c2port_store_flash_access);
  1952. -
  1953. -static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
  1954. -{
  1955. - u8 status;
  1956. - int ret;
  1957. -
  1958. - /* Target the C2 flash programming data register for C2 data register
  1959. - * access.
  1960. - */
  1961. - c2port_write_ar(dev, C2PORT_FPDAT);
  1962. -
  1963. - /* Send device erase command */
  1964. - c2port_write_dr(dev, C2PORT_DEVICE_ERASE);
  1965. -
  1966. - /* Wait for input acknowledge */
  1967. - ret = c2port_poll_in_busy(dev);
  1968. - if (ret < 0)
  1969. - return ret;
  1970. -
  1971. - /* Should check status before starting FLASH access sequence */
  1972. -
  1973. - /* Wait for status information */
  1974. - ret = c2port_poll_out_ready(dev);
  1975. - if (ret < 0)
  1976. - return ret;
  1977. -
  1978. - /* Read flash programming interface status */
  1979. - ret = c2port_read_dr(dev, &status);
  1980. - if (ret < 0)
  1981. - return ret;
  1982. - if (status != C2PORT_COMMAND_OK)
  1983. - return -EBUSY;
  1984. -
  1985. - /* Send a three-byte arming sequence to enable the device erase.
  1986. - * If the sequence is not received correctly, the command will be
  1987. - * ignored.
  1988. - * Sequence is: 0xde, 0xad, 0xa5.
  1989. - */
  1990. - c2port_write_dr(dev, 0xde);
  1991. - ret = c2port_poll_in_busy(dev);
  1992. - if (ret < 0)
  1993. - return ret;
  1994. - c2port_write_dr(dev, 0xad);
  1995. - ret = c2port_poll_in_busy(dev);
  1996. - if (ret < 0)
  1997. - return ret;
  1998. - c2port_write_dr(dev, 0xa5);
  1999. - ret = c2port_poll_in_busy(dev);
  2000. - if (ret < 0)
  2001. - return ret;
  2002. -
  2003. - ret = c2port_poll_out_ready(dev);
  2004. - if (ret < 0)
  2005. - return ret;
  2006. -
  2007. - return 0;
  2008. -}
  2009. -
  2010. -static ssize_t c2port_store_flash_erase(struct device *dev,
  2011. - struct device_attribute *attr,
  2012. - const char *buf, size_t count)
  2013. -{
  2014. - struct c2port_device *c2dev = dev_get_drvdata(dev);
  2015. - int ret;
  2016. -
  2017. - /* Check the device and flash access status */
  2018. - if (!c2dev->access || !c2dev->flash_access)
  2019. - return -EBUSY;
  2020. -
  2021. - mutex_lock(&c2dev->mutex);
  2022. - ret = __c2port_write_flash_erase(c2dev);
  2023. - mutex_unlock(&c2dev->mutex);
  2024. -
  2025. - if (ret < 0) {
  2026. - dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name);
  2027. - return ret;
  2028. - }
  2029. -
  2030. - return count;
  2031. -}
  2032. -static DEVICE_ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase);
  2033. -
  2034. -static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
  2035. - char *buffer, loff_t offset, size_t count)
  2036. -{
  2037. - struct c2port_ops *ops = dev->ops;
  2038. - u8 status, nread = 128;
  2039. - int i, ret;
  2040. -
  2041. - /* Check for flash end */
  2042. - if (offset >= ops->block_size * ops->blocks_num)
  2043. - return 0;
  2044. -
  2045. - if (ops->block_size * ops->blocks_num - offset < nread)
  2046. - nread = ops->block_size * ops->blocks_num - offset;
  2047. - if (count < nread)
  2048. - nread = count;
  2049. - if (nread == 0)
  2050. - return nread;
  2051. -
  2052. - /* Target the C2 flash programming data register for C2 data register
  2053. - * access */
  2054. - c2port_write_ar(dev, C2PORT_FPDAT);
  2055. -
  2056. - /* Send flash block read command */
  2057. - c2port_write_dr(dev, C2PORT_BLOCK_READ);
  2058. -
  2059. - /* Wait for input acknowledge */
  2060. - ret = c2port_poll_in_busy(dev);
  2061. - if (ret < 0)
  2062. - return ret;
  2063. -
  2064. - /* Should check status before starting FLASH access sequence */
  2065. -
  2066. - /* Wait for status information */
  2067. - ret = c2port_poll_out_ready(dev);
  2068. - if (ret < 0)
  2069. - return ret;
  2070. -
  2071. - /* Read flash programming interface status */
  2072. - ret = c2port_read_dr(dev, &status);
  2073. - if (ret < 0)
  2074. - return ret;
  2075. - if (status != C2PORT_COMMAND_OK)
  2076. - return -EBUSY;
  2077. -
  2078. - /* Send address high byte */
  2079. - c2port_write_dr(dev, offset >> 8);
  2080. - ret = c2port_poll_in_busy(dev);
  2081. - if (ret < 0)
  2082. - return ret;
  2083. -
  2084. - /* Send address low byte */
  2085. - c2port_write_dr(dev, offset & 0x00ff);
  2086. - ret = c2port_poll_in_busy(dev);
  2087. - if (ret < 0)
  2088. - return ret;
  2089. -
  2090. - /* Send address block size */
  2091. - c2port_write_dr(dev, nread);
  2092. - ret = c2port_poll_in_busy(dev);
  2093. - if (ret < 0)
  2094. - return ret;
  2095. -
  2096. - /* Should check status before reading FLASH block */
  2097. -
  2098. - /* Wait for status information */
  2099. - ret = c2port_poll_out_ready(dev);
  2100. - if (ret < 0)
  2101. - return ret;
  2102. -
  2103. - /* Read flash programming interface status */
  2104. - ret = c2port_read_dr(dev, &status);
  2105. - if (ret < 0)
  2106. - return ret;
  2107. - if (status != C2PORT_COMMAND_OK)
  2108. - return -EBUSY;
  2109. -
  2110. - /* Read flash block */
  2111. - for (i = 0; i < nread; i++) {
  2112. - ret = c2port_poll_out_ready(dev);
  2113. - if (ret < 0)
  2114. - return ret;
  2115. -
  2116. - ret = c2port_read_dr(dev, buffer+i);
  2117. - if (ret < 0)
  2118. - return ret;
  2119. - }
  2120. -
  2121. - return nread;
  2122. -}
  2123. -
  2124. -static ssize_t c2port_read_flash_data(struct file *filp, struct kobject *kobj,
  2125. - struct bin_attribute *attr,
  2126. - char *buffer, loff_t offset, size_t count)
  2127. -{
  2128. - struct c2port_device *c2dev =
  2129. - dev_get_drvdata(container_of(kobj,
  2130. - struct device, kobj));
  2131. - ssize_t ret;
  2132. -
  2133. - /* Check the device and flash access status */
  2134. - if (!c2dev->access || !c2dev->flash_access)
  2135. - return -EBUSY;
  2136. -
  2137. - mutex_lock(&c2dev->mutex);
  2138. - ret = __c2port_read_flash_data(c2dev, buffer, offset, count);
  2139. - mutex_unlock(&c2dev->mutex);
  2140. -
  2141. - if (ret < 0)
  2142. - dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name);
  2143. -
  2144. - return ret;
  2145. -}
  2146. -
  2147. -static ssize_t __c2port_write_flash_data(struct c2port_device *dev,
  2148. - char *buffer, loff_t offset, size_t count)
  2149. -{
  2150. - struct c2port_ops *ops = dev->ops;
  2151. - u8 status, nwrite = 128;
  2152. - int i, ret;
  2153. -
  2154. - if (nwrite > count)
  2155. - nwrite = count;
  2156. - if (ops->block_size * ops->blocks_num - offset < nwrite)
  2157. - nwrite = ops->block_size * ops->blocks_num - offset;
  2158. -
  2159. - /* Check for flash end */
  2160. - if (offset >= ops->block_size * ops->blocks_num)
  2161. - return -EINVAL;
  2162. -
  2163. - /* Target the C2 flash programming data register for C2 data register
  2164. - * access */
  2165. - c2port_write_ar(dev, C2PORT_FPDAT);
  2166. -
  2167. - /* Send flash block write command */
  2168. - c2port_write_dr(dev, C2PORT_BLOCK_WRITE);
  2169. -
  2170. - /* Wait for input acknowledge */
  2171. - ret = c2port_poll_in_busy(dev);
  2172. - if (ret < 0)
  2173. - return ret;
  2174. -
  2175. - /* Should check status before starting FLASH access sequence */
  2176. -
  2177. - /* Wait for status information */
  2178. - ret = c2port_poll_out_ready(dev);
  2179. - if (ret < 0)
  2180. - return ret;
  2181. -
  2182. - /* Read flash programming interface status */
  2183. - ret = c2port_read_dr(dev, &status);
  2184. - if (ret < 0)
  2185. - return ret;
  2186. - if (status != C2PORT_COMMAND_OK)
  2187. - return -EBUSY;
  2188. -
  2189. - /* Send address high byte */
  2190. - c2port_write_dr(dev, offset >> 8);
  2191. - ret = c2port_poll_in_busy(dev);
  2192. - if (ret < 0)
  2193. - return ret;
  2194. -
  2195. - /* Send address low byte */
  2196. - c2port_write_dr(dev, offset & 0x00ff);
  2197. - ret = c2port_poll_in_busy(dev);
  2198. - if (ret < 0)
  2199. - return ret;
  2200. -
  2201. - /* Send address block size */
  2202. - c2port_write_dr(dev, nwrite);
  2203. - ret = c2port_poll_in_busy(dev);
  2204. - if (ret < 0)
  2205. - return ret;
  2206. -
  2207. - /* Should check status before writing FLASH block */
  2208. -
  2209. - /* Wait for status information */
  2210. - ret = c2port_poll_out_ready(dev);
  2211. - if (ret < 0)
  2212. - return ret;
  2213. -
  2214. - /* Read flash programming interface status */
  2215. - ret = c2port_read_dr(dev, &status);
  2216. - if (ret < 0)
  2217. - return ret;
  2218. - if (status != C2PORT_COMMAND_OK)
  2219. - return -EBUSY;
  2220. -
  2221. - /* Write flash block */
  2222. - for (i = 0; i < nwrite; i++) {
  2223. - ret = c2port_write_dr(dev, *(buffer+i));
  2224. - if (ret < 0)
  2225. - return ret;
  2226. -
  2227. - ret = c2port_poll_in_busy(dev);
  2228. - if (ret < 0)
  2229. - return ret;
  2230. -
  2231. - }
  2232. -
  2233. - /* Wait for last flash write to complete */
  2234. - ret = c2port_poll_out_ready(dev);
  2235. - if (ret < 0)
  2236. - return ret;
  2237. -
  2238. - return nwrite;
  2239. -}
  2240. -
  2241. -static ssize_t c2port_write_flash_data(struct file *filp, struct kobject *kobj,
  2242. - struct bin_attribute *attr,
  2243. - char *buffer, loff_t offset, size_t count)
  2244. -{
  2245. - struct c2port_device *c2dev =
  2246. - dev_get_drvdata(container_of(kobj,
  2247. - struct device, kobj));
  2248. - int ret;
  2249. -
  2250. - /* Check the device access status */
  2251. - if (!c2dev->access || !c2dev->flash_access)
  2252. - return -EBUSY;
  2253. -
  2254. - mutex_lock(&c2dev->mutex);
  2255. - ret = __c2port_write_flash_data(c2dev, buffer, offset, count);
  2256. - mutex_unlock(&c2dev->mutex);
  2257. -
  2258. - if (ret < 0)
  2259. - dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name);
  2260. -
  2261. - return ret;
  2262. -}
  2263. -/* size is computed at run-time */
  2264. -static BIN_ATTR(flash_data, 0644, c2port_read_flash_data,
  2265. - c2port_write_flash_data, 0);
  2266. -
  2267. -/*
  2268. - * Class attributes
  2269. - */
  2270. -static struct attribute *c2port_attrs[] = {
  2271. - &dev_attr_name.attr,
  2272. - &dev_attr_flash_blocks_num.attr,
  2273. - &dev_attr_flash_block_size.attr,
  2274. - &dev_attr_flash_size.attr,
  2275. - &dev_attr_access.attr,
  2276. - &dev_attr_reset.attr,
  2277. - &dev_attr_dev_id.attr,
  2278. - &dev_attr_rev_id.attr,
  2279. - &dev_attr_flash_access.attr,
  2280. - &dev_attr_flash_erase.attr,
  2281. - NULL,
  2282. -};
  2283. -
  2284. -static struct bin_attribute *c2port_bin_attrs[] = {
  2285. - &bin_attr_flash_data,
  2286. - NULL,
  2287. -};
  2288. -
  2289. -static const struct attribute_group c2port_group = {
  2290. - .attrs = c2port_attrs,
  2291. - .bin_attrs = c2port_bin_attrs,
  2292. -};
  2293. -
  2294. -static const struct attribute_group *c2port_groups[] = {
  2295. - &c2port_group,
  2296. - NULL,
  2297. -};
  2298. -
  2299. -/*
  2300. - * Exported functions
  2301. - */
  2302. -
  2303. -struct c2port_device *c2port_device_register(char *name,
  2304. - struct c2port_ops *ops, void *devdata)
  2305. -{
  2306. - struct c2port_device *c2dev;
  2307. - int ret;
  2308. -
  2309. - if (unlikely(!ops) || unlikely(!ops->access) || \
  2310. - unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
  2311. - unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set))
  2312. - return ERR_PTR(-EINVAL);
  2313. -
  2314. - c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL);
  2315. - kmemcheck_annotate_bitfield(c2dev, flags);
  2316. - if (unlikely(!c2dev))
  2317. - return ERR_PTR(-ENOMEM);
  2318. -
  2319. - idr_preload(GFP_KERNEL);
  2320. - spin_lock_irq(&c2port_idr_lock);
  2321. - ret = idr_alloc(&c2port_idr, c2dev, 0, 0, GFP_NOWAIT);
  2322. - spin_unlock_irq(&c2port_idr_lock);
  2323. - idr_preload_end();
  2324. -
  2325. - if (ret < 0)
  2326. - goto error_idr_alloc;
  2327. - c2dev->id = ret;
  2328. -
  2329. - bin_attr_flash_data.size = ops->blocks_num * ops->block_size;
  2330. -
  2331. - c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
  2332. - "c2port%d", c2dev->id);
  2333. - if (unlikely(IS_ERR(c2dev->dev))) {
  2334. - ret = PTR_ERR(c2dev->dev);
  2335. - goto error_device_create;
  2336. - }
  2337. - dev_set_drvdata(c2dev->dev, c2dev);
  2338. -
  2339. - strncpy(c2dev->name, name, C2PORT_NAME_LEN);
  2340. - c2dev->ops = ops;
  2341. - mutex_init(&c2dev->mutex);
  2342. -
  2343. - /* By default C2 port access is off */
  2344. - c2dev->access = c2dev->flash_access = 0;
  2345. - ops->access(c2dev, 0);
  2346. -
  2347. - dev_info(c2dev->dev, "C2 port %s added\n", name);
  2348. - dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes "
  2349. - "(%d bytes total)\n",
  2350. - name, ops->blocks_num, ops->block_size,
  2351. - ops->blocks_num * ops->block_size);
  2352. -
  2353. - return c2dev;
  2354. -
  2355. -error_device_create:
  2356. - spin_lock_irq(&c2port_idr_lock);
  2357. - idr_remove(&c2port_idr, c2dev->id);
  2358. - spin_unlock_irq(&c2port_idr_lock);
  2359. -
  2360. -error_idr_alloc:
  2361. - kfree(c2dev);
  2362. -
  2363. - return ERR_PTR(ret);
  2364. -}
  2365. -EXPORT_SYMBOL(c2port_device_register);
  2366. -
  2367. -void c2port_device_unregister(struct c2port_device *c2dev)
  2368. -{
  2369. - if (!c2dev)
  2370. - return;
  2371. -
  2372. - dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
  2373. -
  2374. - spin_lock_irq(&c2port_idr_lock);
  2375. - idr_remove(&c2port_idr, c2dev->id);
  2376. - spin_unlock_irq(&c2port_idr_lock);
  2377. -
  2378. - device_destroy(c2port_class, c2dev->id);
  2379. -
  2380. - kfree(c2dev);
  2381. -}
  2382. -EXPORT_SYMBOL(c2port_device_unregister);
  2383. -
  2384. -/*
  2385. - * Module stuff
  2386. - */
  2387. -
  2388. -static int __init c2port_init(void)
  2389. -{
  2390. - printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION
  2391. - " - (C) 2007 Rodolfo Giometti\n");
  2392. -
  2393. - c2port_class = class_create(THIS_MODULE, "c2port");
  2394. - if (IS_ERR(c2port_class)) {
  2395. - printk(KERN_ERR "c2port: failed to allocate class\n");
  2396. - return PTR_ERR(c2port_class);
  2397. - }
  2398. - c2port_class->dev_groups = c2port_groups;
  2399. -
  2400. - return 0;
  2401. -}
  2402. -
  2403. -static void __exit c2port_exit(void)
  2404. -{
  2405. - class_destroy(c2port_class);
  2406. -}
  2407. -
  2408. -module_init(c2port_init);
  2409. -module_exit(c2port_exit);
  2410. -
  2411. -MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
  2412. -MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION);
  2413. -MODULE_LICENSE("GPL");
  2414. --
  2415. 1.7.9.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement