xref: /OK3568_Linux_fs/kernel/drivers/mfd/rave-sp.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun 
3*4882a593Smuzhiyun /*
4*4882a593Smuzhiyun  * Multifunction core driver for Zodiac Inflight Innovations RAVE
5*4882a593Smuzhiyun  * Supervisory Processor(SP) MCU that is connected via dedicated UART
6*4882a593Smuzhiyun  * port
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * Copyright (C) 2017 Zodiac Inflight Innovations
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <linux/atomic.h>
12*4882a593Smuzhiyun #include <linux/crc-ccitt.h>
13*4882a593Smuzhiyun #include <linux/delay.h>
14*4882a593Smuzhiyun #include <linux/export.h>
15*4882a593Smuzhiyun #include <linux/init.h>
16*4882a593Smuzhiyun #include <linux/slab.h>
17*4882a593Smuzhiyun #include <linux/kernel.h>
18*4882a593Smuzhiyun #include <linux/mfd/rave-sp.h>
19*4882a593Smuzhiyun #include <linux/module.h>
20*4882a593Smuzhiyun #include <linux/of.h>
21*4882a593Smuzhiyun #include <linux/of_device.h>
22*4882a593Smuzhiyun #include <linux/sched.h>
23*4882a593Smuzhiyun #include <linux/serdev.h>
24*4882a593Smuzhiyun #include <asm/unaligned.h>
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /*
27*4882a593Smuzhiyun  * UART protocol using following entities:
28*4882a593Smuzhiyun  *  - message to MCU => ACK response
29*4882a593Smuzhiyun  *  - event from MCU => event ACK
30*4882a593Smuzhiyun  *
31*4882a593Smuzhiyun  * Frame structure:
32*4882a593Smuzhiyun  * <STX> <DATA> <CHECKSUM> <ETX>
33*4882a593Smuzhiyun  * Where:
34*4882a593Smuzhiyun  * - STX - is start of transmission character
35*4882a593Smuzhiyun  * - ETX - end of transmission
36*4882a593Smuzhiyun  * - DATA - payload
37*4882a593Smuzhiyun  * - CHECKSUM - checksum calculated on <DATA>
38*4882a593Smuzhiyun  *
39*4882a593Smuzhiyun  * If <DATA> or <CHECKSUM> contain one of control characters, then it is
40*4882a593Smuzhiyun  * escaped using <DLE> control code. Added <DLE> does not participate in
41*4882a593Smuzhiyun  * checksum calculation.
42*4882a593Smuzhiyun  */
43*4882a593Smuzhiyun #define RAVE_SP_STX			0x02
44*4882a593Smuzhiyun #define RAVE_SP_ETX			0x03
45*4882a593Smuzhiyun #define RAVE_SP_DLE			0x10
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun #define RAVE_SP_MAX_DATA_SIZE		64
48*4882a593Smuzhiyun #define RAVE_SP_CHECKSUM_8B2C		1
49*4882a593Smuzhiyun #define RAVE_SP_CHECKSUM_CCITT		2
50*4882a593Smuzhiyun #define RAVE_SP_CHECKSUM_SIZE		RAVE_SP_CHECKSUM_CCITT
51*4882a593Smuzhiyun /*
52*4882a593Smuzhiyun  * We don't store STX, ETX and unescaped bytes, so Rx is only
53*4882a593Smuzhiyun  * DATA + CSUM
54*4882a593Smuzhiyun  */
55*4882a593Smuzhiyun #define RAVE_SP_RX_BUFFER_SIZE				\
56*4882a593Smuzhiyun 	(RAVE_SP_MAX_DATA_SIZE + RAVE_SP_CHECKSUM_SIZE)
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun #define RAVE_SP_STX_ETX_SIZE		2
59*4882a593Smuzhiyun /*
60*4882a593Smuzhiyun  * For Tx we have to have space for everything, STX, EXT and
61*4882a593Smuzhiyun  * potentially stuffed DATA + CSUM data + csum
62*4882a593Smuzhiyun  */
63*4882a593Smuzhiyun #define RAVE_SP_TX_BUFFER_SIZE				\
64*4882a593Smuzhiyun 	(RAVE_SP_STX_ETX_SIZE + 2 * RAVE_SP_RX_BUFFER_SIZE)
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun /**
67*4882a593Smuzhiyun  * enum rave_sp_deframer_state - Possible state for de-framer
68*4882a593Smuzhiyun  *
69*4882a593Smuzhiyun  * @RAVE_SP_EXPECT_SOF:		 Scanning input for start-of-frame marker
70*4882a593Smuzhiyun  * @RAVE_SP_EXPECT_DATA:	 Got start of frame marker, collecting frame
71*4882a593Smuzhiyun  * @RAVE_SP_EXPECT_ESCAPED_DATA: Got escape character, collecting escaped byte
72*4882a593Smuzhiyun  */
73*4882a593Smuzhiyun enum rave_sp_deframer_state {
74*4882a593Smuzhiyun 	RAVE_SP_EXPECT_SOF,
75*4882a593Smuzhiyun 	RAVE_SP_EXPECT_DATA,
76*4882a593Smuzhiyun 	RAVE_SP_EXPECT_ESCAPED_DATA,
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /**
80*4882a593Smuzhiyun  * struct rave_sp_deframer - Device protocol deframer
81*4882a593Smuzhiyun  *
82*4882a593Smuzhiyun  * @state:  Current state of the deframer
83*4882a593Smuzhiyun  * @data:   Buffer used to collect deframed data
84*4882a593Smuzhiyun  * @length: Number of bytes de-framed so far
85*4882a593Smuzhiyun  */
86*4882a593Smuzhiyun struct rave_sp_deframer {
87*4882a593Smuzhiyun 	enum rave_sp_deframer_state state;
88*4882a593Smuzhiyun 	unsigned char data[RAVE_SP_RX_BUFFER_SIZE];
89*4882a593Smuzhiyun 	size_t length;
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /**
93*4882a593Smuzhiyun  * struct rave_sp_reply - Reply as per RAVE device protocol
94*4882a593Smuzhiyun  *
95*4882a593Smuzhiyun  * @length:	Expected reply length
96*4882a593Smuzhiyun  * @data:	Buffer to store reply payload in
97*4882a593Smuzhiyun  * @code:	Expected reply code
98*4882a593Smuzhiyun  * @ackid:	Expected reply ACK ID
99*4882a593Smuzhiyun  * @received:   Successful reply reception completion
100*4882a593Smuzhiyun  */
101*4882a593Smuzhiyun struct rave_sp_reply {
102*4882a593Smuzhiyun 	size_t length;
103*4882a593Smuzhiyun 	void  *data;
104*4882a593Smuzhiyun 	u8     code;
105*4882a593Smuzhiyun 	u8     ackid;
106*4882a593Smuzhiyun 	struct completion received;
107*4882a593Smuzhiyun };
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun /**
110*4882a593Smuzhiyun  * struct rave_sp_checksum - Variant specific checksum implementation details
111*4882a593Smuzhiyun  *
112*4882a593Smuzhiyun  * @length:	Calculated checksum length
113*4882a593Smuzhiyun  * @subroutine:	Utilized checksum algorithm implementation
114*4882a593Smuzhiyun  */
115*4882a593Smuzhiyun struct rave_sp_checksum {
116*4882a593Smuzhiyun 	size_t length;
117*4882a593Smuzhiyun 	void (*subroutine)(const u8 *, size_t, u8 *);
118*4882a593Smuzhiyun };
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun struct rave_sp_version {
121*4882a593Smuzhiyun 	u8     hardware;
122*4882a593Smuzhiyun 	__le16 major;
123*4882a593Smuzhiyun 	u8     minor;
124*4882a593Smuzhiyun 	u8     letter[2];
125*4882a593Smuzhiyun } __packed;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun struct rave_sp_status {
128*4882a593Smuzhiyun 	struct rave_sp_version bootloader_version;
129*4882a593Smuzhiyun 	struct rave_sp_version firmware_version;
130*4882a593Smuzhiyun 	u16 rdu_eeprom_flag;
131*4882a593Smuzhiyun 	u16 dds_eeprom_flag;
132*4882a593Smuzhiyun 	u8  pic_flag;
133*4882a593Smuzhiyun 	u8  orientation;
134*4882a593Smuzhiyun 	u32 etc;
135*4882a593Smuzhiyun 	s16 temp[2];
136*4882a593Smuzhiyun 	u8  backlight_current[3];
137*4882a593Smuzhiyun 	u8  dip_switch;
138*4882a593Smuzhiyun 	u8  host_interrupt;
139*4882a593Smuzhiyun 	u16 voltage_28;
140*4882a593Smuzhiyun 	u8  i2c_device_status;
141*4882a593Smuzhiyun 	u8  power_status;
142*4882a593Smuzhiyun 	u8  general_status;
143*4882a593Smuzhiyun 	u8  deprecated1;
144*4882a593Smuzhiyun 	u8  power_led_status;
145*4882a593Smuzhiyun 	u8  deprecated2;
146*4882a593Smuzhiyun 	u8  periph_power_shutoff;
147*4882a593Smuzhiyun } __packed;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun /**
150*4882a593Smuzhiyun  * struct rave_sp_variant_cmds - Variant specific command routines
151*4882a593Smuzhiyun  *
152*4882a593Smuzhiyun  * @translate:	Generic to variant specific command mapping routine
153*4882a593Smuzhiyun  * @get_status: Variant specific implementation of CMD_GET_STATUS
154*4882a593Smuzhiyun  */
155*4882a593Smuzhiyun struct rave_sp_variant_cmds {
156*4882a593Smuzhiyun 	int (*translate)(enum rave_sp_command);
157*4882a593Smuzhiyun 	int (*get_status)(struct rave_sp *sp, struct rave_sp_status *);
158*4882a593Smuzhiyun };
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /**
161*4882a593Smuzhiyun  * struct rave_sp_variant - RAVE supervisory processor core variant
162*4882a593Smuzhiyun  *
163*4882a593Smuzhiyun  * @checksum:	Variant specific checksum implementation
164*4882a593Smuzhiyun  * @cmd:	Variant specific command pointer table
165*4882a593Smuzhiyun  *
166*4882a593Smuzhiyun  */
167*4882a593Smuzhiyun struct rave_sp_variant {
168*4882a593Smuzhiyun 	const struct rave_sp_checksum *checksum;
169*4882a593Smuzhiyun 	struct rave_sp_variant_cmds cmd;
170*4882a593Smuzhiyun };
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun /**
173*4882a593Smuzhiyun  * struct rave_sp - RAVE supervisory processor core
174*4882a593Smuzhiyun  *
175*4882a593Smuzhiyun  * @serdev:			Pointer to underlying serdev
176*4882a593Smuzhiyun  * @deframer:			Stored state of the protocol deframer
177*4882a593Smuzhiyun  * @ackid:			ACK ID used in last reply sent to the device
178*4882a593Smuzhiyun  * @bus_lock:			Lock to serialize access to the device
179*4882a593Smuzhiyun  * @reply_lock:			Lock protecting @reply
180*4882a593Smuzhiyun  * @reply:			Pointer to memory to store reply payload
181*4882a593Smuzhiyun  *
182*4882a593Smuzhiyun  * @variant:			Device variant specific information
183*4882a593Smuzhiyun  * @event_notifier_list:	Input event notification chain
184*4882a593Smuzhiyun  *
185*4882a593Smuzhiyun  * @part_number_firmware:	Firmware version
186*4882a593Smuzhiyun  * @part_number_bootloader:	Bootloader version
187*4882a593Smuzhiyun  */
188*4882a593Smuzhiyun struct rave_sp {
189*4882a593Smuzhiyun 	struct serdev_device *serdev;
190*4882a593Smuzhiyun 	struct rave_sp_deframer deframer;
191*4882a593Smuzhiyun 	atomic_t ackid;
192*4882a593Smuzhiyun 	struct mutex bus_lock;
193*4882a593Smuzhiyun 	struct mutex reply_lock;
194*4882a593Smuzhiyun 	struct rave_sp_reply *reply;
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	const struct rave_sp_variant *variant;
197*4882a593Smuzhiyun 	struct blocking_notifier_head event_notifier_list;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	const char *part_number_firmware;
200*4882a593Smuzhiyun 	const char *part_number_bootloader;
201*4882a593Smuzhiyun };
202*4882a593Smuzhiyun 
rave_sp_id_is_event(u8 code)203*4882a593Smuzhiyun static bool rave_sp_id_is_event(u8 code)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun 	return (code & 0xF0) == RAVE_SP_EVNT_BASE;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
rave_sp_unregister_event_notifier(struct device * dev,void * res)208*4882a593Smuzhiyun static void rave_sp_unregister_event_notifier(struct device *dev, void *res)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	struct rave_sp *sp = dev_get_drvdata(dev->parent);
211*4882a593Smuzhiyun 	struct notifier_block *nb = *(struct notifier_block **)res;
212*4882a593Smuzhiyun 	struct blocking_notifier_head *bnh = &sp->event_notifier_list;
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	WARN_ON(blocking_notifier_chain_unregister(bnh, nb));
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun 
devm_rave_sp_register_event_notifier(struct device * dev,struct notifier_block * nb)217*4882a593Smuzhiyun int devm_rave_sp_register_event_notifier(struct device *dev,
218*4882a593Smuzhiyun 					 struct notifier_block *nb)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun 	struct rave_sp *sp = dev_get_drvdata(dev->parent);
221*4882a593Smuzhiyun 	struct notifier_block **rcnb;
222*4882a593Smuzhiyun 	int ret;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	rcnb = devres_alloc(rave_sp_unregister_event_notifier,
225*4882a593Smuzhiyun 			    sizeof(*rcnb), GFP_KERNEL);
226*4882a593Smuzhiyun 	if (!rcnb)
227*4882a593Smuzhiyun 		return -ENOMEM;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	ret = blocking_notifier_chain_register(&sp->event_notifier_list, nb);
230*4882a593Smuzhiyun 	if (!ret) {
231*4882a593Smuzhiyun 		*rcnb = nb;
232*4882a593Smuzhiyun 		devres_add(dev, rcnb);
233*4882a593Smuzhiyun 	} else {
234*4882a593Smuzhiyun 		devres_free(rcnb);
235*4882a593Smuzhiyun 	}
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	return ret;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(devm_rave_sp_register_event_notifier);
240*4882a593Smuzhiyun 
csum_8b2c(const u8 * buf,size_t size,u8 * crc)241*4882a593Smuzhiyun static void csum_8b2c(const u8 *buf, size_t size, u8 *crc)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun 	*crc = *buf++;
244*4882a593Smuzhiyun 	size--;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	while (size--)
247*4882a593Smuzhiyun 		*crc += *buf++;
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	*crc = 1 + ~(*crc);
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun 
csum_ccitt(const u8 * buf,size_t size,u8 * crc)252*4882a593Smuzhiyun static void csum_ccitt(const u8 *buf, size_t size, u8 *crc)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun 	const u16 calculated = crc_ccitt_false(0xffff, buf, size);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	/*
257*4882a593Smuzhiyun 	 * While the rest of the wire protocol is little-endian,
258*4882a593Smuzhiyun 	 * CCITT-16 CRC in RDU2 device is sent out in big-endian order.
259*4882a593Smuzhiyun 	 */
260*4882a593Smuzhiyun 	put_unaligned_be16(calculated, crc);
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun 
stuff(unsigned char * dest,const unsigned char * src,size_t n)263*4882a593Smuzhiyun static void *stuff(unsigned char *dest, const unsigned char *src, size_t n)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun 	while (n--) {
266*4882a593Smuzhiyun 		const unsigned char byte = *src++;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 		switch (byte) {
269*4882a593Smuzhiyun 		case RAVE_SP_STX:
270*4882a593Smuzhiyun 		case RAVE_SP_ETX:
271*4882a593Smuzhiyun 		case RAVE_SP_DLE:
272*4882a593Smuzhiyun 			*dest++ = RAVE_SP_DLE;
273*4882a593Smuzhiyun 			fallthrough;
274*4882a593Smuzhiyun 		default:
275*4882a593Smuzhiyun 			*dest++ = byte;
276*4882a593Smuzhiyun 		}
277*4882a593Smuzhiyun 	}
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	return dest;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun 
rave_sp_write(struct rave_sp * sp,const u8 * data,u8 data_size)282*4882a593Smuzhiyun static int rave_sp_write(struct rave_sp *sp, const u8 *data, u8 data_size)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	const size_t checksum_length = sp->variant->checksum->length;
285*4882a593Smuzhiyun 	unsigned char frame[RAVE_SP_TX_BUFFER_SIZE];
286*4882a593Smuzhiyun 	unsigned char crc[RAVE_SP_CHECKSUM_SIZE];
287*4882a593Smuzhiyun 	unsigned char *dest = frame;
288*4882a593Smuzhiyun 	size_t length;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	if (WARN_ON(checksum_length > sizeof(crc)))
291*4882a593Smuzhiyun 		return -ENOMEM;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	if (WARN_ON(data_size > sizeof(frame)))
294*4882a593Smuzhiyun 		return -ENOMEM;
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	sp->variant->checksum->subroutine(data, data_size, crc);
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	*dest++ = RAVE_SP_STX;
299*4882a593Smuzhiyun 	dest = stuff(dest, data, data_size);
300*4882a593Smuzhiyun 	dest = stuff(dest, crc, checksum_length);
301*4882a593Smuzhiyun 	*dest++ = RAVE_SP_ETX;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	length = dest - frame;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	print_hex_dump_debug("rave-sp tx: ", DUMP_PREFIX_NONE,
306*4882a593Smuzhiyun 			     16, 1, frame, length, false);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	return serdev_device_write(sp->serdev, frame, length, HZ);
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun 
rave_sp_reply_code(u8 command)311*4882a593Smuzhiyun static u8 rave_sp_reply_code(u8 command)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun 	/*
314*4882a593Smuzhiyun 	 * There isn't a single rule that describes command code ->
315*4882a593Smuzhiyun 	 * ACK code transformation, but, going through various
316*4882a593Smuzhiyun 	 * versions of ICDs, there appear to be three distinct groups
317*4882a593Smuzhiyun 	 * that can be described by simple transformation.
318*4882a593Smuzhiyun 	 */
319*4882a593Smuzhiyun 	switch (command) {
320*4882a593Smuzhiyun 	case 0xA0 ... 0xBE:
321*4882a593Smuzhiyun 		/*
322*4882a593Smuzhiyun 		 * Commands implemented by firmware found in RDU1 and
323*4882a593Smuzhiyun 		 * older devices all seem to obey the following rule
324*4882a593Smuzhiyun 		 */
325*4882a593Smuzhiyun 		return command + 0x20;
326*4882a593Smuzhiyun 	case 0xE0 ... 0xEF:
327*4882a593Smuzhiyun 		/*
328*4882a593Smuzhiyun 		 * Events emitted by all versions of the firmare use
329*4882a593Smuzhiyun 		 * least significant bit to get an ACK code
330*4882a593Smuzhiyun 		 */
331*4882a593Smuzhiyun 		return command | 0x01;
332*4882a593Smuzhiyun 	default:
333*4882a593Smuzhiyun 		/*
334*4882a593Smuzhiyun 		 * Commands implemented by firmware found in RDU2 are
335*4882a593Smuzhiyun 		 * similar to "old" commands, but they use slightly
336*4882a593Smuzhiyun 		 * different offset
337*4882a593Smuzhiyun 		 */
338*4882a593Smuzhiyun 		return command + 0x40;
339*4882a593Smuzhiyun 	}
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun 
rave_sp_exec(struct rave_sp * sp,void * __data,size_t data_size,void * reply_data,size_t reply_data_size)342*4882a593Smuzhiyun int rave_sp_exec(struct rave_sp *sp,
343*4882a593Smuzhiyun 		 void *__data,  size_t data_size,
344*4882a593Smuzhiyun 		 void *reply_data, size_t reply_data_size)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun 	struct rave_sp_reply reply = {
347*4882a593Smuzhiyun 		.data     = reply_data,
348*4882a593Smuzhiyun 		.length   = reply_data_size,
349*4882a593Smuzhiyun 		.received = COMPLETION_INITIALIZER_ONSTACK(reply.received),
350*4882a593Smuzhiyun 	};
351*4882a593Smuzhiyun 	unsigned char *data = __data;
352*4882a593Smuzhiyun 	int command, ret = 0;
353*4882a593Smuzhiyun 	u8 ackid;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	command = sp->variant->cmd.translate(data[0]);
356*4882a593Smuzhiyun 	if (command < 0)
357*4882a593Smuzhiyun 		return command;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	ackid       = atomic_inc_return(&sp->ackid);
360*4882a593Smuzhiyun 	reply.ackid = ackid;
361*4882a593Smuzhiyun 	reply.code  = rave_sp_reply_code((u8)command),
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	mutex_lock(&sp->bus_lock);
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	mutex_lock(&sp->reply_lock);
366*4882a593Smuzhiyun 	sp->reply = &reply;
367*4882a593Smuzhiyun 	mutex_unlock(&sp->reply_lock);
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	data[0] = command;
370*4882a593Smuzhiyun 	data[1] = ackid;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	rave_sp_write(sp, data, data_size);
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	if (!wait_for_completion_timeout(&reply.received, HZ)) {
375*4882a593Smuzhiyun 		dev_err(&sp->serdev->dev, "Command timeout\n");
376*4882a593Smuzhiyun 		ret = -ETIMEDOUT;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 		mutex_lock(&sp->reply_lock);
379*4882a593Smuzhiyun 		sp->reply = NULL;
380*4882a593Smuzhiyun 		mutex_unlock(&sp->reply_lock);
381*4882a593Smuzhiyun 	}
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	mutex_unlock(&sp->bus_lock);
384*4882a593Smuzhiyun 	return ret;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rave_sp_exec);
387*4882a593Smuzhiyun 
rave_sp_receive_event(struct rave_sp * sp,const unsigned char * data,size_t length)388*4882a593Smuzhiyun static void rave_sp_receive_event(struct rave_sp *sp,
389*4882a593Smuzhiyun 				  const unsigned char *data, size_t length)
390*4882a593Smuzhiyun {
391*4882a593Smuzhiyun 	u8 cmd[] = {
392*4882a593Smuzhiyun 		[0] = rave_sp_reply_code(data[0]),
393*4882a593Smuzhiyun 		[1] = data[1],
394*4882a593Smuzhiyun 	};
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	rave_sp_write(sp, cmd, sizeof(cmd));
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	blocking_notifier_call_chain(&sp->event_notifier_list,
399*4882a593Smuzhiyun 				     rave_sp_action_pack(data[0], data[2]),
400*4882a593Smuzhiyun 				     NULL);
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun 
rave_sp_receive_reply(struct rave_sp * sp,const unsigned char * data,size_t length)403*4882a593Smuzhiyun static void rave_sp_receive_reply(struct rave_sp *sp,
404*4882a593Smuzhiyun 				  const unsigned char *data, size_t length)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun 	struct device *dev = &sp->serdev->dev;
407*4882a593Smuzhiyun 	struct rave_sp_reply *reply;
408*4882a593Smuzhiyun 	const  size_t payload_length = length - 2;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	mutex_lock(&sp->reply_lock);
411*4882a593Smuzhiyun 	reply = sp->reply;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	if (reply) {
414*4882a593Smuzhiyun 		if (reply->code == data[0] && reply->ackid == data[1] &&
415*4882a593Smuzhiyun 		    payload_length >= reply->length) {
416*4882a593Smuzhiyun 			/*
417*4882a593Smuzhiyun 			 * We are relying on memcpy(dst, src, 0) to be a no-op
418*4882a593Smuzhiyun 			 * when handling commands that have a no-payload reply
419*4882a593Smuzhiyun 			 */
420*4882a593Smuzhiyun 			memcpy(reply->data, &data[2], reply->length);
421*4882a593Smuzhiyun 			complete(&reply->received);
422*4882a593Smuzhiyun 			sp->reply = NULL;
423*4882a593Smuzhiyun 		} else {
424*4882a593Smuzhiyun 			dev_err(dev, "Ignoring incorrect reply\n");
425*4882a593Smuzhiyun 			dev_dbg(dev, "Code:   expected = 0x%08x received = 0x%08x\n",
426*4882a593Smuzhiyun 				reply->code, data[0]);
427*4882a593Smuzhiyun 			dev_dbg(dev, "ACK ID: expected = 0x%08x received = 0x%08x\n",
428*4882a593Smuzhiyun 				reply->ackid, data[1]);
429*4882a593Smuzhiyun 			dev_dbg(dev, "Length: expected = %zu received = %zu\n",
430*4882a593Smuzhiyun 				reply->length, payload_length);
431*4882a593Smuzhiyun 		}
432*4882a593Smuzhiyun 	}
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	mutex_unlock(&sp->reply_lock);
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun 
rave_sp_receive_frame(struct rave_sp * sp,const unsigned char * data,size_t length)437*4882a593Smuzhiyun static void rave_sp_receive_frame(struct rave_sp *sp,
438*4882a593Smuzhiyun 				  const unsigned char *data,
439*4882a593Smuzhiyun 				  size_t length)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun 	const size_t checksum_length = sp->variant->checksum->length;
442*4882a593Smuzhiyun 	const size_t payload_length  = length - checksum_length;
443*4882a593Smuzhiyun 	const u8 *crc_reported       = &data[payload_length];
444*4882a593Smuzhiyun 	struct device *dev           = &sp->serdev->dev;
445*4882a593Smuzhiyun 	u8 crc_calculated[RAVE_SP_CHECKSUM_SIZE];
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	if (unlikely(checksum_length > sizeof(crc_calculated))) {
448*4882a593Smuzhiyun 		dev_warn(dev, "Checksum too long, dropping\n");
449*4882a593Smuzhiyun 		return;
450*4882a593Smuzhiyun 	}
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	print_hex_dump_debug("rave-sp rx: ", DUMP_PREFIX_NONE,
453*4882a593Smuzhiyun 			     16, 1, data, length, false);
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	if (unlikely(length <= checksum_length)) {
456*4882a593Smuzhiyun 		dev_warn(dev, "Dropping short frame\n");
457*4882a593Smuzhiyun 		return;
458*4882a593Smuzhiyun 	}
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	sp->variant->checksum->subroutine(data, payload_length,
461*4882a593Smuzhiyun 					  crc_calculated);
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	if (memcmp(crc_calculated, crc_reported, checksum_length)) {
464*4882a593Smuzhiyun 		dev_warn(dev, "Dropping bad frame\n");
465*4882a593Smuzhiyun 		return;
466*4882a593Smuzhiyun 	}
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	if (rave_sp_id_is_event(data[0]))
469*4882a593Smuzhiyun 		rave_sp_receive_event(sp, data, length);
470*4882a593Smuzhiyun 	else
471*4882a593Smuzhiyun 		rave_sp_receive_reply(sp, data, length);
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun 
rave_sp_receive_buf(struct serdev_device * serdev,const unsigned char * buf,size_t size)474*4882a593Smuzhiyun static int rave_sp_receive_buf(struct serdev_device *serdev,
475*4882a593Smuzhiyun 			       const unsigned char *buf, size_t size)
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun 	struct device *dev = &serdev->dev;
478*4882a593Smuzhiyun 	struct rave_sp *sp = dev_get_drvdata(dev);
479*4882a593Smuzhiyun 	struct rave_sp_deframer *deframer = &sp->deframer;
480*4882a593Smuzhiyun 	const unsigned char *src = buf;
481*4882a593Smuzhiyun 	const unsigned char *end = buf + size;
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	while (src < end) {
484*4882a593Smuzhiyun 		const unsigned char byte = *src++;
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 		switch (deframer->state) {
487*4882a593Smuzhiyun 		case RAVE_SP_EXPECT_SOF:
488*4882a593Smuzhiyun 			if (byte == RAVE_SP_STX)
489*4882a593Smuzhiyun 				deframer->state = RAVE_SP_EXPECT_DATA;
490*4882a593Smuzhiyun 			break;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 		case RAVE_SP_EXPECT_DATA:
493*4882a593Smuzhiyun 			/*
494*4882a593Smuzhiyun 			 * Treat special byte values first
495*4882a593Smuzhiyun 			 */
496*4882a593Smuzhiyun 			switch (byte) {
497*4882a593Smuzhiyun 			case RAVE_SP_ETX:
498*4882a593Smuzhiyun 				rave_sp_receive_frame(sp,
499*4882a593Smuzhiyun 						      deframer->data,
500*4882a593Smuzhiyun 						      deframer->length);
501*4882a593Smuzhiyun 				/*
502*4882a593Smuzhiyun 				 * Once we extracted a complete frame
503*4882a593Smuzhiyun 				 * out of a stream, we call it done
504*4882a593Smuzhiyun 				 * and proceed to bailing out while
505*4882a593Smuzhiyun 				 * resetting the framer to initial
506*4882a593Smuzhiyun 				 * state, regardless if we've consumed
507*4882a593Smuzhiyun 				 * all of the stream or not.
508*4882a593Smuzhiyun 				 */
509*4882a593Smuzhiyun 				goto reset_framer;
510*4882a593Smuzhiyun 			case RAVE_SP_STX:
511*4882a593Smuzhiyun 				dev_warn(dev, "Bad frame: STX before ETX\n");
512*4882a593Smuzhiyun 				/*
513*4882a593Smuzhiyun 				 * If we encounter second "start of
514*4882a593Smuzhiyun 				 * the frame" marker before seeing
515*4882a593Smuzhiyun 				 * corresponding "end of frame", we
516*4882a593Smuzhiyun 				 * reset the framer and ignore both:
517*4882a593Smuzhiyun 				 * frame started by first SOF and
518*4882a593Smuzhiyun 				 * frame started by current SOF.
519*4882a593Smuzhiyun 				 *
520*4882a593Smuzhiyun 				 * NOTE: The above means that only the
521*4882a593Smuzhiyun 				 * frame started by third SOF, sent
522*4882a593Smuzhiyun 				 * after this one will have a chance
523*4882a593Smuzhiyun 				 * to get throught.
524*4882a593Smuzhiyun 				 */
525*4882a593Smuzhiyun 				goto reset_framer;
526*4882a593Smuzhiyun 			case RAVE_SP_DLE:
527*4882a593Smuzhiyun 				deframer->state = RAVE_SP_EXPECT_ESCAPED_DATA;
528*4882a593Smuzhiyun 				/*
529*4882a593Smuzhiyun 				 * If we encounter escape sequence we
530*4882a593Smuzhiyun 				 * need to skip it and collect the
531*4882a593Smuzhiyun 				 * byte that follows. We do it by
532*4882a593Smuzhiyun 				 * forcing the next iteration of the
533*4882a593Smuzhiyun 				 * encompassing while loop.
534*4882a593Smuzhiyun 				 */
535*4882a593Smuzhiyun 				continue;
536*4882a593Smuzhiyun 			}
537*4882a593Smuzhiyun 			/*
538*4882a593Smuzhiyun 			 * For the rest of the bytes, that are not
539*4882a593Smuzhiyun 			 * speical snoflakes, we do the same thing
540*4882a593Smuzhiyun 			 * that we do to escaped data - collect it in
541*4882a593Smuzhiyun 			 * deframer buffer
542*4882a593Smuzhiyun 			 */
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 			fallthrough;
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 		case RAVE_SP_EXPECT_ESCAPED_DATA:
547*4882a593Smuzhiyun 			if (deframer->length == sizeof(deframer->data)) {
548*4882a593Smuzhiyun 				dev_warn(dev, "Bad frame: Too long\n");
549*4882a593Smuzhiyun 				/*
550*4882a593Smuzhiyun 				 * If the amount of data we've
551*4882a593Smuzhiyun 				 * accumulated for current frame so
552*4882a593Smuzhiyun 				 * far starts to exceed the capacity
553*4882a593Smuzhiyun 				 * of deframer's buffer, there's
554*4882a593Smuzhiyun 				 * nothing else we can do but to
555*4882a593Smuzhiyun 				 * discard that data and start
556*4882a593Smuzhiyun 				 * assemblying a new frame again
557*4882a593Smuzhiyun 				 */
558*4882a593Smuzhiyun 				goto reset_framer;
559*4882a593Smuzhiyun 			}
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 			deframer->data[deframer->length++] = byte;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 			/*
564*4882a593Smuzhiyun 			 * We've extracted out special byte, now we
565*4882a593Smuzhiyun 			 * can go back to regular data collecting
566*4882a593Smuzhiyun 			 */
567*4882a593Smuzhiyun 			deframer->state = RAVE_SP_EXPECT_DATA;
568*4882a593Smuzhiyun 			break;
569*4882a593Smuzhiyun 		}
570*4882a593Smuzhiyun 	}
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	/*
573*4882a593Smuzhiyun 	 * The only way to get out of the above loop and end up here
574*4882a593Smuzhiyun 	 * is throught consuming all of the supplied data, so here we
575*4882a593Smuzhiyun 	 * report that we processed it all.
576*4882a593Smuzhiyun 	 */
577*4882a593Smuzhiyun 	return size;
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun reset_framer:
580*4882a593Smuzhiyun 	/*
581*4882a593Smuzhiyun 	 * NOTE: A number of codepaths that will drop us here will do
582*4882a593Smuzhiyun 	 * so before consuming all 'size' bytes of the data passed by
583*4882a593Smuzhiyun 	 * serdev layer. We rely on the fact that serdev layer will
584*4882a593Smuzhiyun 	 * re-execute this handler with the remainder of the Rx bytes
585*4882a593Smuzhiyun 	 * once we report actual number of bytes that we processed.
586*4882a593Smuzhiyun 	 */
587*4882a593Smuzhiyun 	deframer->state  = RAVE_SP_EXPECT_SOF;
588*4882a593Smuzhiyun 	deframer->length = 0;
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	return src - buf;
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun 
rave_sp_rdu1_cmd_translate(enum rave_sp_command command)593*4882a593Smuzhiyun static int rave_sp_rdu1_cmd_translate(enum rave_sp_command command)
594*4882a593Smuzhiyun {
595*4882a593Smuzhiyun 	if (command >= RAVE_SP_CMD_STATUS &&
596*4882a593Smuzhiyun 	    command <= RAVE_SP_CMD_CONTROL_EVENTS)
597*4882a593Smuzhiyun 		return command;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	return -EINVAL;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun 
rave_sp_rdu2_cmd_translate(enum rave_sp_command command)602*4882a593Smuzhiyun static int rave_sp_rdu2_cmd_translate(enum rave_sp_command command)
603*4882a593Smuzhiyun {
604*4882a593Smuzhiyun 	if (command >= RAVE_SP_CMD_GET_FIRMWARE_VERSION &&
605*4882a593Smuzhiyun 	    command <= RAVE_SP_CMD_GET_GPIO_STATE)
606*4882a593Smuzhiyun 		return command;
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun 	if (command == RAVE_SP_CMD_REQ_COPPER_REV) {
609*4882a593Smuzhiyun 		/*
610*4882a593Smuzhiyun 		 * As per RDU2 ICD 3.4.47 CMD_GET_COPPER_REV code is
611*4882a593Smuzhiyun 		 * different from that for RDU1 and it is set to 0x28.
612*4882a593Smuzhiyun 		 */
613*4882a593Smuzhiyun 		return 0x28;
614*4882a593Smuzhiyun 	}
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	return rave_sp_rdu1_cmd_translate(command);
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun 
rave_sp_default_cmd_translate(enum rave_sp_command command)619*4882a593Smuzhiyun static int rave_sp_default_cmd_translate(enum rave_sp_command command)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun 	/*
622*4882a593Smuzhiyun 	 * All of the following command codes were taken from "Table :
623*4882a593Smuzhiyun 	 * Communications Protocol Message Types" in section 3.3
624*4882a593Smuzhiyun 	 * "MESSAGE TYPES" of Rave PIC24 ICD.
625*4882a593Smuzhiyun 	 */
626*4882a593Smuzhiyun 	switch (command) {
627*4882a593Smuzhiyun 	case RAVE_SP_CMD_GET_FIRMWARE_VERSION:
628*4882a593Smuzhiyun 		return 0x11;
629*4882a593Smuzhiyun 	case RAVE_SP_CMD_GET_BOOTLOADER_VERSION:
630*4882a593Smuzhiyun 		return 0x12;
631*4882a593Smuzhiyun 	case RAVE_SP_CMD_BOOT_SOURCE:
632*4882a593Smuzhiyun 		return 0x14;
633*4882a593Smuzhiyun 	case RAVE_SP_CMD_SW_WDT:
634*4882a593Smuzhiyun 		return 0x1C;
635*4882a593Smuzhiyun 	case RAVE_SP_CMD_PET_WDT:
636*4882a593Smuzhiyun 		return 0x1D;
637*4882a593Smuzhiyun 	case RAVE_SP_CMD_RESET:
638*4882a593Smuzhiyun 		return 0x1E;
639*4882a593Smuzhiyun 	case RAVE_SP_CMD_RESET_REASON:
640*4882a593Smuzhiyun 		return 0x1F;
641*4882a593Smuzhiyun 	case RAVE_SP_CMD_RMB_EEPROM:
642*4882a593Smuzhiyun 		return 0x20;
643*4882a593Smuzhiyun 	default:
644*4882a593Smuzhiyun 		return -EINVAL;
645*4882a593Smuzhiyun 	}
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun 
devm_rave_sp_version(struct device * dev,struct rave_sp_version * version)648*4882a593Smuzhiyun static const char *devm_rave_sp_version(struct device *dev,
649*4882a593Smuzhiyun 					struct rave_sp_version *version)
650*4882a593Smuzhiyun {
651*4882a593Smuzhiyun 	/*
652*4882a593Smuzhiyun 	 * NOTE: The format string below uses %02d to display u16
653*4882a593Smuzhiyun 	 * intentionally for the sake of backwards compatibility with
654*4882a593Smuzhiyun 	 * legacy software.
655*4882a593Smuzhiyun 	 */
656*4882a593Smuzhiyun 	return devm_kasprintf(dev, GFP_KERNEL, "%02d%02d%02d.%c%c\n",
657*4882a593Smuzhiyun 			      version->hardware,
658*4882a593Smuzhiyun 			      le16_to_cpu(version->major),
659*4882a593Smuzhiyun 			      version->minor,
660*4882a593Smuzhiyun 			      version->letter[0],
661*4882a593Smuzhiyun 			      version->letter[1]);
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun 
rave_sp_rdu1_get_status(struct rave_sp * sp,struct rave_sp_status * status)664*4882a593Smuzhiyun static int rave_sp_rdu1_get_status(struct rave_sp *sp,
665*4882a593Smuzhiyun 				   struct rave_sp_status *status)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun 	u8 cmd[] = {
668*4882a593Smuzhiyun 		[0] = RAVE_SP_CMD_STATUS,
669*4882a593Smuzhiyun 		[1] = 0
670*4882a593Smuzhiyun 	};
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	return rave_sp_exec(sp, cmd, sizeof(cmd), status, sizeof(*status));
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun 
rave_sp_emulated_get_status(struct rave_sp * sp,struct rave_sp_status * status)675*4882a593Smuzhiyun static int rave_sp_emulated_get_status(struct rave_sp *sp,
676*4882a593Smuzhiyun 				       struct rave_sp_status *status)
677*4882a593Smuzhiyun {
678*4882a593Smuzhiyun 	u8 cmd[] = {
679*4882a593Smuzhiyun 		[0] = RAVE_SP_CMD_GET_FIRMWARE_VERSION,
680*4882a593Smuzhiyun 		[1] = 0,
681*4882a593Smuzhiyun 	};
682*4882a593Smuzhiyun 	int ret;
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	ret = rave_sp_exec(sp, cmd, sizeof(cmd), &status->firmware_version,
685*4882a593Smuzhiyun 			   sizeof(status->firmware_version));
686*4882a593Smuzhiyun 	if (ret)
687*4882a593Smuzhiyun 		return ret;
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	cmd[0] = RAVE_SP_CMD_GET_BOOTLOADER_VERSION;
690*4882a593Smuzhiyun 	return rave_sp_exec(sp, cmd, sizeof(cmd), &status->bootloader_version,
691*4882a593Smuzhiyun 			    sizeof(status->bootloader_version));
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun 
rave_sp_get_status(struct rave_sp * sp)694*4882a593Smuzhiyun static int rave_sp_get_status(struct rave_sp *sp)
695*4882a593Smuzhiyun {
696*4882a593Smuzhiyun 	struct device *dev = &sp->serdev->dev;
697*4882a593Smuzhiyun 	struct rave_sp_status status;
698*4882a593Smuzhiyun 	const char *version;
699*4882a593Smuzhiyun 	int ret;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	ret = sp->variant->cmd.get_status(sp, &status);
702*4882a593Smuzhiyun 	if (ret)
703*4882a593Smuzhiyun 		return ret;
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	version = devm_rave_sp_version(dev, &status.firmware_version);
706*4882a593Smuzhiyun 	if (!version)
707*4882a593Smuzhiyun 		return -ENOMEM;
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	sp->part_number_firmware = version;
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun 	version = devm_rave_sp_version(dev, &status.bootloader_version);
712*4882a593Smuzhiyun 	if (!version)
713*4882a593Smuzhiyun 		return -ENOMEM;
714*4882a593Smuzhiyun 
715*4882a593Smuzhiyun 	sp->part_number_bootloader = version;
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	return 0;
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun static const struct rave_sp_checksum rave_sp_checksum_8b2c = {
721*4882a593Smuzhiyun 	.length     = 1,
722*4882a593Smuzhiyun 	.subroutine = csum_8b2c,
723*4882a593Smuzhiyun };
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun static const struct rave_sp_checksum rave_sp_checksum_ccitt = {
726*4882a593Smuzhiyun 	.length     = 2,
727*4882a593Smuzhiyun 	.subroutine = csum_ccitt,
728*4882a593Smuzhiyun };
729*4882a593Smuzhiyun 
730*4882a593Smuzhiyun static const struct rave_sp_variant rave_sp_legacy = {
731*4882a593Smuzhiyun 	.checksum = &rave_sp_checksum_ccitt,
732*4882a593Smuzhiyun 	.cmd = {
733*4882a593Smuzhiyun 		.translate = rave_sp_default_cmd_translate,
734*4882a593Smuzhiyun 		.get_status = rave_sp_emulated_get_status,
735*4882a593Smuzhiyun 	},
736*4882a593Smuzhiyun };
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun static const struct rave_sp_variant rave_sp_rdu1 = {
739*4882a593Smuzhiyun 	.checksum = &rave_sp_checksum_8b2c,
740*4882a593Smuzhiyun 	.cmd = {
741*4882a593Smuzhiyun 		.translate = rave_sp_rdu1_cmd_translate,
742*4882a593Smuzhiyun 		.get_status = rave_sp_rdu1_get_status,
743*4882a593Smuzhiyun 	},
744*4882a593Smuzhiyun };
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun static const struct rave_sp_variant rave_sp_rdu2 = {
747*4882a593Smuzhiyun 	.checksum = &rave_sp_checksum_ccitt,
748*4882a593Smuzhiyun 	.cmd = {
749*4882a593Smuzhiyun 		.translate = rave_sp_rdu2_cmd_translate,
750*4882a593Smuzhiyun 		.get_status = rave_sp_emulated_get_status,
751*4882a593Smuzhiyun 	},
752*4882a593Smuzhiyun };
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun static const struct of_device_id rave_sp_dt_ids[] = {
755*4882a593Smuzhiyun 	{ .compatible = "zii,rave-sp-niu",  .data = &rave_sp_legacy },
756*4882a593Smuzhiyun 	{ .compatible = "zii,rave-sp-mezz", .data = &rave_sp_legacy },
757*4882a593Smuzhiyun 	{ .compatible = "zii,rave-sp-esb",  .data = &rave_sp_legacy },
758*4882a593Smuzhiyun 	{ .compatible = "zii,rave-sp-rdu1", .data = &rave_sp_rdu1   },
759*4882a593Smuzhiyun 	{ .compatible = "zii,rave-sp-rdu2", .data = &rave_sp_rdu2   },
760*4882a593Smuzhiyun 	{ /* sentinel */ }
761*4882a593Smuzhiyun };
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun static const struct serdev_device_ops rave_sp_serdev_device_ops = {
764*4882a593Smuzhiyun 	.receive_buf  = rave_sp_receive_buf,
765*4882a593Smuzhiyun 	.write_wakeup = serdev_device_write_wakeup,
766*4882a593Smuzhiyun };
767*4882a593Smuzhiyun 
rave_sp_probe(struct serdev_device * serdev)768*4882a593Smuzhiyun static int rave_sp_probe(struct serdev_device *serdev)
769*4882a593Smuzhiyun {
770*4882a593Smuzhiyun 	struct device *dev = &serdev->dev;
771*4882a593Smuzhiyun 	const char *unknown = "unknown\n";
772*4882a593Smuzhiyun 	struct rave_sp *sp;
773*4882a593Smuzhiyun 	u32 baud;
774*4882a593Smuzhiyun 	int ret;
775*4882a593Smuzhiyun 
776*4882a593Smuzhiyun 	if (of_property_read_u32(dev->of_node, "current-speed", &baud)) {
777*4882a593Smuzhiyun 		dev_err(dev,
778*4882a593Smuzhiyun 			"'current-speed' is not specified in device node\n");
779*4882a593Smuzhiyun 		return -EINVAL;
780*4882a593Smuzhiyun 	}
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL);
783*4882a593Smuzhiyun 	if (!sp)
784*4882a593Smuzhiyun 		return -ENOMEM;
785*4882a593Smuzhiyun 
786*4882a593Smuzhiyun 	sp->serdev = serdev;
787*4882a593Smuzhiyun 	dev_set_drvdata(dev, sp);
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	sp->variant = of_device_get_match_data(dev);
790*4882a593Smuzhiyun 	if (!sp->variant)
791*4882a593Smuzhiyun 		return -ENODEV;
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun 	mutex_init(&sp->bus_lock);
794*4882a593Smuzhiyun 	mutex_init(&sp->reply_lock);
795*4882a593Smuzhiyun 	BLOCKING_INIT_NOTIFIER_HEAD(&sp->event_notifier_list);
796*4882a593Smuzhiyun 
797*4882a593Smuzhiyun 	serdev_device_set_client_ops(serdev, &rave_sp_serdev_device_ops);
798*4882a593Smuzhiyun 	ret = devm_serdev_device_open(dev, serdev);
799*4882a593Smuzhiyun 	if (ret)
800*4882a593Smuzhiyun 		return ret;
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 	serdev_device_set_baudrate(serdev, baud);
803*4882a593Smuzhiyun 	serdev_device_set_flow_control(serdev, false);
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE);
806*4882a593Smuzhiyun 	if (ret) {
807*4882a593Smuzhiyun 		dev_err(dev, "Failed to set parity\n");
808*4882a593Smuzhiyun 		return ret;
809*4882a593Smuzhiyun 	}
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun 	ret = rave_sp_get_status(sp);
812*4882a593Smuzhiyun 	if (ret) {
813*4882a593Smuzhiyun 		dev_warn(dev, "Failed to get firmware status: %d\n", ret);
814*4882a593Smuzhiyun 		sp->part_number_firmware   = unknown;
815*4882a593Smuzhiyun 		sp->part_number_bootloader = unknown;
816*4882a593Smuzhiyun 	}
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun 	/*
819*4882a593Smuzhiyun 	 * Those strings already have a \n embedded, so there's no
820*4882a593Smuzhiyun 	 * need to have one in format string.
821*4882a593Smuzhiyun 	 */
822*4882a593Smuzhiyun 	dev_info(dev, "Firmware version: %s",   sp->part_number_firmware);
823*4882a593Smuzhiyun 	dev_info(dev, "Bootloader version: %s", sp->part_number_bootloader);
824*4882a593Smuzhiyun 
825*4882a593Smuzhiyun 	return devm_of_platform_populate(dev);
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rave_sp_dt_ids);
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun static struct serdev_device_driver rave_sp_drv = {
831*4882a593Smuzhiyun 	.probe			= rave_sp_probe,
832*4882a593Smuzhiyun 	.driver = {
833*4882a593Smuzhiyun 		.name		= "rave-sp",
834*4882a593Smuzhiyun 		.of_match_table	= rave_sp_dt_ids,
835*4882a593Smuzhiyun 	},
836*4882a593Smuzhiyun };
837*4882a593Smuzhiyun module_serdev_device_driver(rave_sp_drv);
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun MODULE_LICENSE("GPL");
840*4882a593Smuzhiyun MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>");
841*4882a593Smuzhiyun MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>");
842*4882a593Smuzhiyun MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
843*4882a593Smuzhiyun MODULE_DESCRIPTION("RAVE SP core driver");
844