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