1538ee272SAndrey Smirnov // SPDX-License-Identifier: GPL-2.0+ 2538ee272SAndrey Smirnov 3538ee272SAndrey Smirnov /* 4538ee272SAndrey Smirnov * Multifunction core driver for Zodiac Inflight Innovations RAVE 5538ee272SAndrey Smirnov * Supervisory Processor(SP) MCU that is connected via dedicated UART 6538ee272SAndrey Smirnov * port 7538ee272SAndrey Smirnov * 8538ee272SAndrey Smirnov * Copyright (C) 2017 Zodiac Inflight Innovations 9538ee272SAndrey Smirnov */ 10538ee272SAndrey Smirnov 11538ee272SAndrey Smirnov #include <linux/atomic.h> 12538ee272SAndrey Smirnov #include <linux/crc-ccitt.h> 13538ee272SAndrey Smirnov #include <linux/delay.h> 14538ee272SAndrey Smirnov #include <linux/export.h> 15538ee272SAndrey Smirnov #include <linux/init.h> 16538ee272SAndrey Smirnov #include <linux/slab.h> 17538ee272SAndrey Smirnov #include <linux/kernel.h> 18538ee272SAndrey Smirnov #include <linux/mfd/rave-sp.h> 19538ee272SAndrey Smirnov #include <linux/module.h> 20538ee272SAndrey Smirnov #include <linux/of.h> 21538ee272SAndrey Smirnov #include <linux/of_device.h> 22538ee272SAndrey Smirnov #include <linux/sched.h> 23538ee272SAndrey Smirnov #include <linux/serdev.h> 24538ee272SAndrey Smirnov #include <asm/unaligned.h> 25538ee272SAndrey Smirnov 26538ee272SAndrey Smirnov /* 27538ee272SAndrey Smirnov * UART protocol using following entities: 28538ee272SAndrey Smirnov * - message to MCU => ACK response 29538ee272SAndrey Smirnov * - event from MCU => event ACK 30538ee272SAndrey Smirnov * 31538ee272SAndrey Smirnov * Frame structure: 32538ee272SAndrey Smirnov * <STX> <DATA> <CHECKSUM> <ETX> 33538ee272SAndrey Smirnov * Where: 34538ee272SAndrey Smirnov * - STX - is start of transmission character 35538ee272SAndrey Smirnov * - ETX - end of transmission 36538ee272SAndrey Smirnov * - DATA - payload 37538ee272SAndrey Smirnov * - CHECKSUM - checksum calculated on <DATA> 38538ee272SAndrey Smirnov * 39538ee272SAndrey Smirnov * If <DATA> or <CHECKSUM> contain one of control characters, then it is 40538ee272SAndrey Smirnov * escaped using <DLE> control code. Added <DLE> does not participate in 41538ee272SAndrey Smirnov * checksum calculation. 42538ee272SAndrey Smirnov */ 43538ee272SAndrey Smirnov #define RAVE_SP_STX 0x02 44538ee272SAndrey Smirnov #define RAVE_SP_ETX 0x03 45538ee272SAndrey Smirnov #define RAVE_SP_DLE 0x10 46538ee272SAndrey Smirnov 47538ee272SAndrey Smirnov #define RAVE_SP_MAX_DATA_SIZE 64 487169483cSKyle Spiers #define RAVE_SP_CHECKSUM_8B2C 1 497169483cSKyle Spiers #define RAVE_SP_CHECKSUM_CCITT 2 507169483cSKyle Spiers #define RAVE_SP_CHECKSUM_SIZE RAVE_SP_CHECKSUM_CCITT 51538ee272SAndrey Smirnov /* 52538ee272SAndrey Smirnov * We don't store STX, ETX and unescaped bytes, so Rx is only 53538ee272SAndrey Smirnov * DATA + CSUM 54538ee272SAndrey Smirnov */ 55538ee272SAndrey Smirnov #define RAVE_SP_RX_BUFFER_SIZE \ 56538ee272SAndrey Smirnov (RAVE_SP_MAX_DATA_SIZE + RAVE_SP_CHECKSUM_SIZE) 57538ee272SAndrey Smirnov 58538ee272SAndrey Smirnov #define RAVE_SP_STX_ETX_SIZE 2 59538ee272SAndrey Smirnov /* 60538ee272SAndrey Smirnov * For Tx we have to have space for everything, STX, EXT and 61538ee272SAndrey Smirnov * potentially stuffed DATA + CSUM data + csum 62538ee272SAndrey Smirnov */ 63538ee272SAndrey Smirnov #define RAVE_SP_TX_BUFFER_SIZE \ 64538ee272SAndrey Smirnov (RAVE_SP_STX_ETX_SIZE + 2 * RAVE_SP_RX_BUFFER_SIZE) 65538ee272SAndrey Smirnov 66538ee272SAndrey Smirnov /** 67538ee272SAndrey Smirnov * enum rave_sp_deframer_state - Possible state for de-framer 68538ee272SAndrey Smirnov * 69538ee272SAndrey Smirnov * @RAVE_SP_EXPECT_SOF: Scanning input for start-of-frame marker 70538ee272SAndrey Smirnov * @RAVE_SP_EXPECT_DATA: Got start of frame marker, collecting frame 71538ee272SAndrey Smirnov * @RAVE_SP_EXPECT_ESCAPED_DATA: Got escape character, collecting escaped byte 72538ee272SAndrey Smirnov */ 73538ee272SAndrey Smirnov enum rave_sp_deframer_state { 74538ee272SAndrey Smirnov RAVE_SP_EXPECT_SOF, 75538ee272SAndrey Smirnov RAVE_SP_EXPECT_DATA, 76538ee272SAndrey Smirnov RAVE_SP_EXPECT_ESCAPED_DATA, 77538ee272SAndrey Smirnov }; 78538ee272SAndrey Smirnov 79538ee272SAndrey Smirnov /** 80538ee272SAndrey Smirnov * struct rave_sp_deframer - Device protocol deframer 81538ee272SAndrey Smirnov * 82538ee272SAndrey Smirnov * @state: Current state of the deframer 83538ee272SAndrey Smirnov * @data: Buffer used to collect deframed data 84538ee272SAndrey Smirnov * @length: Number of bytes de-framed so far 85538ee272SAndrey Smirnov */ 86538ee272SAndrey Smirnov struct rave_sp_deframer { 87538ee272SAndrey Smirnov enum rave_sp_deframer_state state; 88538ee272SAndrey Smirnov unsigned char data[RAVE_SP_RX_BUFFER_SIZE]; 89538ee272SAndrey Smirnov size_t length; 90538ee272SAndrey Smirnov }; 91538ee272SAndrey Smirnov 92538ee272SAndrey Smirnov /** 93538ee272SAndrey Smirnov * struct rave_sp_reply - Reply as per RAVE device protocol 94538ee272SAndrey Smirnov * 95538ee272SAndrey Smirnov * @length: Expected reply length 96538ee272SAndrey Smirnov * @data: Buffer to store reply payload in 97538ee272SAndrey Smirnov * @code: Expected reply code 98538ee272SAndrey Smirnov * @ackid: Expected reply ACK ID 99538ee272SAndrey Smirnov * @completion: Successful reply reception completion 100538ee272SAndrey Smirnov */ 101538ee272SAndrey Smirnov struct rave_sp_reply { 102538ee272SAndrey Smirnov size_t length; 103538ee272SAndrey Smirnov void *data; 104538ee272SAndrey Smirnov u8 code; 105538ee272SAndrey Smirnov u8 ackid; 106538ee272SAndrey Smirnov struct completion received; 107538ee272SAndrey Smirnov }; 108538ee272SAndrey Smirnov 109538ee272SAndrey Smirnov /** 110538ee272SAndrey Smirnov * struct rave_sp_checksum - Variant specific checksum implementation details 111538ee272SAndrey Smirnov * 112538ee272SAndrey Smirnov * @length: Caculated checksum length 113538ee272SAndrey Smirnov * @subroutine: Utilized checksum algorithm implementation 114538ee272SAndrey Smirnov */ 115538ee272SAndrey Smirnov struct rave_sp_checksum { 116538ee272SAndrey Smirnov size_t length; 117538ee272SAndrey Smirnov void (*subroutine)(const u8 *, size_t, u8 *); 118538ee272SAndrey Smirnov }; 119538ee272SAndrey Smirnov 120538ee272SAndrey Smirnov /** 121538ee272SAndrey Smirnov * struct rave_sp_variant_cmds - Variant specific command routines 122538ee272SAndrey Smirnov * 123538ee272SAndrey Smirnov * @translate: Generic to variant specific command mapping routine 124538ee272SAndrey Smirnov * 125538ee272SAndrey Smirnov */ 126538ee272SAndrey Smirnov struct rave_sp_variant_cmds { 127538ee272SAndrey Smirnov int (*translate)(enum rave_sp_command); 128538ee272SAndrey Smirnov }; 129538ee272SAndrey Smirnov 130538ee272SAndrey Smirnov /** 131538ee272SAndrey Smirnov * struct rave_sp_variant - RAVE supervisory processor core variant 132538ee272SAndrey Smirnov * 133538ee272SAndrey Smirnov * @checksum: Variant specific checksum implementation 134538ee272SAndrey Smirnov * @cmd: Variant specific command pointer table 135538ee272SAndrey Smirnov * 136538ee272SAndrey Smirnov */ 137538ee272SAndrey Smirnov struct rave_sp_variant { 138538ee272SAndrey Smirnov const struct rave_sp_checksum *checksum; 139538ee272SAndrey Smirnov struct rave_sp_variant_cmds cmd; 140538ee272SAndrey Smirnov }; 141538ee272SAndrey Smirnov 142538ee272SAndrey Smirnov /** 143538ee272SAndrey Smirnov * struct rave_sp - RAVE supervisory processor core 144538ee272SAndrey Smirnov * 145538ee272SAndrey Smirnov * @serdev: Pointer to underlying serdev 146538ee272SAndrey Smirnov * @deframer: Stored state of the protocol deframer 147538ee272SAndrey Smirnov * @ackid: ACK ID used in last reply sent to the device 148538ee272SAndrey Smirnov * @bus_lock: Lock to serialize access to the device 149538ee272SAndrey Smirnov * @reply_lock: Lock protecting @reply 150538ee272SAndrey Smirnov * @reply: Pointer to memory to store reply payload 151538ee272SAndrey Smirnov * 152538ee272SAndrey Smirnov * @variant: Device variant specific information 153538ee272SAndrey Smirnov * @event_notifier_list: Input event notification chain 154538ee272SAndrey Smirnov * 1556d97b6f1SAndrey Smirnov * @part_number_firmware: Firmware version 1566d97b6f1SAndrey Smirnov * @part_number_bootloader: Bootloader version 157538ee272SAndrey Smirnov */ 158538ee272SAndrey Smirnov struct rave_sp { 159538ee272SAndrey Smirnov struct serdev_device *serdev; 160538ee272SAndrey Smirnov struct rave_sp_deframer deframer; 161538ee272SAndrey Smirnov atomic_t ackid; 162538ee272SAndrey Smirnov struct mutex bus_lock; 163538ee272SAndrey Smirnov struct mutex reply_lock; 164538ee272SAndrey Smirnov struct rave_sp_reply *reply; 165538ee272SAndrey Smirnov 166538ee272SAndrey Smirnov const struct rave_sp_variant *variant; 167538ee272SAndrey Smirnov struct blocking_notifier_head event_notifier_list; 1686d97b6f1SAndrey Smirnov 1696d97b6f1SAndrey Smirnov const char *part_number_firmware; 1706d97b6f1SAndrey Smirnov const char *part_number_bootloader; 171538ee272SAndrey Smirnov }; 172538ee272SAndrey Smirnov 1736d97b6f1SAndrey Smirnov struct rave_sp_version { 1746d97b6f1SAndrey Smirnov u8 hardware; 1756d97b6f1SAndrey Smirnov __le16 major; 1766d97b6f1SAndrey Smirnov u8 minor; 1776d97b6f1SAndrey Smirnov u8 letter[2]; 1786d97b6f1SAndrey Smirnov } __packed; 1796d97b6f1SAndrey Smirnov 1806d97b6f1SAndrey Smirnov struct rave_sp_status { 1816d97b6f1SAndrey Smirnov struct rave_sp_version bootloader_version; 1826d97b6f1SAndrey Smirnov struct rave_sp_version firmware_version; 1836d97b6f1SAndrey Smirnov u16 rdu_eeprom_flag; 1846d97b6f1SAndrey Smirnov u16 dds_eeprom_flag; 1856d97b6f1SAndrey Smirnov u8 pic_flag; 1866d97b6f1SAndrey Smirnov u8 orientation; 1876d97b6f1SAndrey Smirnov u32 etc; 1886d97b6f1SAndrey Smirnov s16 temp[2]; 1896d97b6f1SAndrey Smirnov u8 backlight_current[3]; 1906d97b6f1SAndrey Smirnov u8 dip_switch; 1916d97b6f1SAndrey Smirnov u8 host_interrupt; 1926d97b6f1SAndrey Smirnov u16 voltage_28; 1936d97b6f1SAndrey Smirnov u8 i2c_device_status; 1946d97b6f1SAndrey Smirnov u8 power_status; 1956d97b6f1SAndrey Smirnov u8 general_status; 1966d97b6f1SAndrey Smirnov u8 deprecated1; 1976d97b6f1SAndrey Smirnov u8 power_led_status; 1986d97b6f1SAndrey Smirnov u8 deprecated2; 1996d97b6f1SAndrey Smirnov u8 periph_power_shutoff; 2006d97b6f1SAndrey Smirnov } __packed; 2016d97b6f1SAndrey Smirnov 202538ee272SAndrey Smirnov static bool rave_sp_id_is_event(u8 code) 203538ee272SAndrey Smirnov { 204538ee272SAndrey Smirnov return (code & 0xF0) == RAVE_SP_EVNT_BASE; 205538ee272SAndrey Smirnov } 206538ee272SAndrey Smirnov 207538ee272SAndrey Smirnov static void rave_sp_unregister_event_notifier(struct device *dev, void *res) 208538ee272SAndrey Smirnov { 209538ee272SAndrey Smirnov struct rave_sp *sp = dev_get_drvdata(dev->parent); 210538ee272SAndrey Smirnov struct notifier_block *nb = *(struct notifier_block **)res; 211538ee272SAndrey Smirnov struct blocking_notifier_head *bnh = &sp->event_notifier_list; 212538ee272SAndrey Smirnov 213538ee272SAndrey Smirnov WARN_ON(blocking_notifier_chain_unregister(bnh, nb)); 214538ee272SAndrey Smirnov } 215538ee272SAndrey Smirnov 216538ee272SAndrey Smirnov int devm_rave_sp_register_event_notifier(struct device *dev, 217538ee272SAndrey Smirnov struct notifier_block *nb) 218538ee272SAndrey Smirnov { 219538ee272SAndrey Smirnov struct rave_sp *sp = dev_get_drvdata(dev->parent); 220538ee272SAndrey Smirnov struct notifier_block **rcnb; 221538ee272SAndrey Smirnov int ret; 222538ee272SAndrey Smirnov 223538ee272SAndrey Smirnov rcnb = devres_alloc(rave_sp_unregister_event_notifier, 224538ee272SAndrey Smirnov sizeof(*rcnb), GFP_KERNEL); 225538ee272SAndrey Smirnov if (!rcnb) 226538ee272SAndrey Smirnov return -ENOMEM; 227538ee272SAndrey Smirnov 228538ee272SAndrey Smirnov ret = blocking_notifier_chain_register(&sp->event_notifier_list, nb); 229538ee272SAndrey Smirnov if (!ret) { 230538ee272SAndrey Smirnov *rcnb = nb; 231538ee272SAndrey Smirnov devres_add(dev, rcnb); 232538ee272SAndrey Smirnov } else { 233538ee272SAndrey Smirnov devres_free(rcnb); 234538ee272SAndrey Smirnov } 235538ee272SAndrey Smirnov 236538ee272SAndrey Smirnov return ret; 237538ee272SAndrey Smirnov } 238538ee272SAndrey Smirnov EXPORT_SYMBOL_GPL(devm_rave_sp_register_event_notifier); 239538ee272SAndrey Smirnov 240538ee272SAndrey Smirnov static void csum_8b2c(const u8 *buf, size_t size, u8 *crc) 241538ee272SAndrey Smirnov { 242538ee272SAndrey Smirnov *crc = *buf++; 243538ee272SAndrey Smirnov size--; 244538ee272SAndrey Smirnov 245538ee272SAndrey Smirnov while (size--) 246538ee272SAndrey Smirnov *crc += *buf++; 247538ee272SAndrey Smirnov 248538ee272SAndrey Smirnov *crc = 1 + ~(*crc); 249538ee272SAndrey Smirnov } 250538ee272SAndrey Smirnov 251538ee272SAndrey Smirnov static void csum_ccitt(const u8 *buf, size_t size, u8 *crc) 252538ee272SAndrey Smirnov { 253538ee272SAndrey Smirnov const u16 calculated = crc_ccitt_false(0xffff, buf, size); 254538ee272SAndrey Smirnov 255538ee272SAndrey Smirnov /* 256538ee272SAndrey Smirnov * While the rest of the wire protocol is little-endian, 257538ee272SAndrey Smirnov * CCITT-16 CRC in RDU2 device is sent out in big-endian order. 258538ee272SAndrey Smirnov */ 259538ee272SAndrey Smirnov put_unaligned_be16(calculated, crc); 260538ee272SAndrey Smirnov } 261538ee272SAndrey Smirnov 262538ee272SAndrey Smirnov static void *stuff(unsigned char *dest, const unsigned char *src, size_t n) 263538ee272SAndrey Smirnov { 264538ee272SAndrey Smirnov while (n--) { 265538ee272SAndrey Smirnov const unsigned char byte = *src++; 266538ee272SAndrey Smirnov 267538ee272SAndrey Smirnov switch (byte) { 268538ee272SAndrey Smirnov case RAVE_SP_STX: 269538ee272SAndrey Smirnov case RAVE_SP_ETX: 270538ee272SAndrey Smirnov case RAVE_SP_DLE: 271538ee272SAndrey Smirnov *dest++ = RAVE_SP_DLE; 272538ee272SAndrey Smirnov /* FALLTHROUGH */ 273538ee272SAndrey Smirnov default: 274538ee272SAndrey Smirnov *dest++ = byte; 275538ee272SAndrey Smirnov } 276538ee272SAndrey Smirnov } 277538ee272SAndrey Smirnov 278538ee272SAndrey Smirnov return dest; 279538ee272SAndrey Smirnov } 280538ee272SAndrey Smirnov 281538ee272SAndrey Smirnov static int rave_sp_write(struct rave_sp *sp, const u8 *data, u8 data_size) 282538ee272SAndrey Smirnov { 283538ee272SAndrey Smirnov const size_t checksum_length = sp->variant->checksum->length; 284538ee272SAndrey Smirnov unsigned char frame[RAVE_SP_TX_BUFFER_SIZE]; 285538ee272SAndrey Smirnov unsigned char crc[RAVE_SP_CHECKSUM_SIZE]; 286538ee272SAndrey Smirnov unsigned char *dest = frame; 287538ee272SAndrey Smirnov size_t length; 288538ee272SAndrey Smirnov 289538ee272SAndrey Smirnov if (WARN_ON(checksum_length > sizeof(crc))) 290538ee272SAndrey Smirnov return -ENOMEM; 291538ee272SAndrey Smirnov 292538ee272SAndrey Smirnov if (WARN_ON(data_size > sizeof(frame))) 293538ee272SAndrey Smirnov return -ENOMEM; 294538ee272SAndrey Smirnov 295538ee272SAndrey Smirnov sp->variant->checksum->subroutine(data, data_size, crc); 296538ee272SAndrey Smirnov 297538ee272SAndrey Smirnov *dest++ = RAVE_SP_STX; 298538ee272SAndrey Smirnov dest = stuff(dest, data, data_size); 299538ee272SAndrey Smirnov dest = stuff(dest, crc, checksum_length); 300538ee272SAndrey Smirnov *dest++ = RAVE_SP_ETX; 301538ee272SAndrey Smirnov 302538ee272SAndrey Smirnov length = dest - frame; 303538ee272SAndrey Smirnov 30444564bc3SAndrey Smirnov print_hex_dump_debug("rave-sp tx: ", DUMP_PREFIX_NONE, 305538ee272SAndrey Smirnov 16, 1, frame, length, false); 306538ee272SAndrey Smirnov 307538ee272SAndrey Smirnov return serdev_device_write(sp->serdev, frame, length, HZ); 308538ee272SAndrey Smirnov } 309538ee272SAndrey Smirnov 310538ee272SAndrey Smirnov static u8 rave_sp_reply_code(u8 command) 311538ee272SAndrey Smirnov { 312538ee272SAndrey Smirnov /* 313538ee272SAndrey Smirnov * There isn't a single rule that describes command code -> 314538ee272SAndrey Smirnov * ACK code transformation, but, going through various 315538ee272SAndrey Smirnov * versions of ICDs, there appear to be three distinct groups 316538ee272SAndrey Smirnov * that can be described by simple transformation. 317538ee272SAndrey Smirnov */ 318538ee272SAndrey Smirnov switch (command) { 319538ee272SAndrey Smirnov case 0xA0 ... 0xBE: 320538ee272SAndrey Smirnov /* 321538ee272SAndrey Smirnov * Commands implemented by firmware found in RDU1 and 322538ee272SAndrey Smirnov * older devices all seem to obey the following rule 323538ee272SAndrey Smirnov */ 324538ee272SAndrey Smirnov return command + 0x20; 325538ee272SAndrey Smirnov case 0xE0 ... 0xEF: 326538ee272SAndrey Smirnov /* 327538ee272SAndrey Smirnov * Events emitted by all versions of the firmare use 328538ee272SAndrey Smirnov * least significant bit to get an ACK code 329538ee272SAndrey Smirnov */ 330538ee272SAndrey Smirnov return command | 0x01; 331538ee272SAndrey Smirnov default: 332538ee272SAndrey Smirnov /* 333538ee272SAndrey Smirnov * Commands implemented by firmware found in RDU2 are 334538ee272SAndrey Smirnov * similar to "old" commands, but they use slightly 335538ee272SAndrey Smirnov * different offset 336538ee272SAndrey Smirnov */ 337538ee272SAndrey Smirnov return command + 0x40; 338538ee272SAndrey Smirnov } 339538ee272SAndrey Smirnov } 340538ee272SAndrey Smirnov 341538ee272SAndrey Smirnov int rave_sp_exec(struct rave_sp *sp, 342538ee272SAndrey Smirnov void *__data, size_t data_size, 343538ee272SAndrey Smirnov void *reply_data, size_t reply_data_size) 344538ee272SAndrey Smirnov { 345538ee272SAndrey Smirnov struct rave_sp_reply reply = { 346538ee272SAndrey Smirnov .data = reply_data, 347538ee272SAndrey Smirnov .length = reply_data_size, 348538ee272SAndrey Smirnov .received = COMPLETION_INITIALIZER_ONSTACK(reply.received), 349538ee272SAndrey Smirnov }; 350538ee272SAndrey Smirnov unsigned char *data = __data; 351538ee272SAndrey Smirnov int command, ret = 0; 352538ee272SAndrey Smirnov u8 ackid; 353538ee272SAndrey Smirnov 354538ee272SAndrey Smirnov command = sp->variant->cmd.translate(data[0]); 355538ee272SAndrey Smirnov if (command < 0) 356538ee272SAndrey Smirnov return command; 357538ee272SAndrey Smirnov 358538ee272SAndrey Smirnov ackid = atomic_inc_return(&sp->ackid); 359538ee272SAndrey Smirnov reply.ackid = ackid; 360538ee272SAndrey Smirnov reply.code = rave_sp_reply_code((u8)command), 361538ee272SAndrey Smirnov 362538ee272SAndrey Smirnov mutex_lock(&sp->bus_lock); 363538ee272SAndrey Smirnov 364538ee272SAndrey Smirnov mutex_lock(&sp->reply_lock); 365538ee272SAndrey Smirnov sp->reply = &reply; 366538ee272SAndrey Smirnov mutex_unlock(&sp->reply_lock); 367538ee272SAndrey Smirnov 368538ee272SAndrey Smirnov data[0] = command; 369538ee272SAndrey Smirnov data[1] = ackid; 370538ee272SAndrey Smirnov 371538ee272SAndrey Smirnov rave_sp_write(sp, data, data_size); 372538ee272SAndrey Smirnov 373538ee272SAndrey Smirnov if (!wait_for_completion_timeout(&reply.received, HZ)) { 374538ee272SAndrey Smirnov dev_err(&sp->serdev->dev, "Command timeout\n"); 375538ee272SAndrey Smirnov ret = -ETIMEDOUT; 376538ee272SAndrey Smirnov 377538ee272SAndrey Smirnov mutex_lock(&sp->reply_lock); 378538ee272SAndrey Smirnov sp->reply = NULL; 379538ee272SAndrey Smirnov mutex_unlock(&sp->reply_lock); 380538ee272SAndrey Smirnov } 381538ee272SAndrey Smirnov 382538ee272SAndrey Smirnov mutex_unlock(&sp->bus_lock); 383538ee272SAndrey Smirnov return ret; 384538ee272SAndrey Smirnov } 385538ee272SAndrey Smirnov EXPORT_SYMBOL_GPL(rave_sp_exec); 386538ee272SAndrey Smirnov 387538ee272SAndrey Smirnov static void rave_sp_receive_event(struct rave_sp *sp, 388538ee272SAndrey Smirnov const unsigned char *data, size_t length) 389538ee272SAndrey Smirnov { 390538ee272SAndrey Smirnov u8 cmd[] = { 391538ee272SAndrey Smirnov [0] = rave_sp_reply_code(data[0]), 392538ee272SAndrey Smirnov [1] = data[1], 393538ee272SAndrey Smirnov }; 394538ee272SAndrey Smirnov 395538ee272SAndrey Smirnov rave_sp_write(sp, cmd, sizeof(cmd)); 396538ee272SAndrey Smirnov 397538ee272SAndrey Smirnov blocking_notifier_call_chain(&sp->event_notifier_list, 398538ee272SAndrey Smirnov rave_sp_action_pack(data[0], data[2]), 399538ee272SAndrey Smirnov NULL); 400538ee272SAndrey Smirnov } 401538ee272SAndrey Smirnov 402538ee272SAndrey Smirnov static void rave_sp_receive_reply(struct rave_sp *sp, 403538ee272SAndrey Smirnov const unsigned char *data, size_t length) 404538ee272SAndrey Smirnov { 405538ee272SAndrey Smirnov struct device *dev = &sp->serdev->dev; 406538ee272SAndrey Smirnov struct rave_sp_reply *reply; 407538ee272SAndrey Smirnov const size_t payload_length = length - 2; 408538ee272SAndrey Smirnov 409538ee272SAndrey Smirnov mutex_lock(&sp->reply_lock); 410538ee272SAndrey Smirnov reply = sp->reply; 411538ee272SAndrey Smirnov 412538ee272SAndrey Smirnov if (reply) { 413538ee272SAndrey Smirnov if (reply->code == data[0] && reply->ackid == data[1] && 414538ee272SAndrey Smirnov payload_length >= reply->length) { 415538ee272SAndrey Smirnov /* 416538ee272SAndrey Smirnov * We are relying on memcpy(dst, src, 0) to be a no-op 417538ee272SAndrey Smirnov * when handling commands that have a no-payload reply 418538ee272SAndrey Smirnov */ 419538ee272SAndrey Smirnov memcpy(reply->data, &data[2], reply->length); 420538ee272SAndrey Smirnov complete(&reply->received); 421538ee272SAndrey Smirnov sp->reply = NULL; 422538ee272SAndrey Smirnov } else { 423538ee272SAndrey Smirnov dev_err(dev, "Ignoring incorrect reply\n"); 424538ee272SAndrey Smirnov dev_dbg(dev, "Code: expected = 0x%08x received = 0x%08x\n", 425538ee272SAndrey Smirnov reply->code, data[0]); 426538ee272SAndrey Smirnov dev_dbg(dev, "ACK ID: expected = 0x%08x received = 0x%08x\n", 427538ee272SAndrey Smirnov reply->ackid, data[1]); 428538ee272SAndrey Smirnov dev_dbg(dev, "Length: expected = %zu received = %zu\n", 429538ee272SAndrey Smirnov reply->length, payload_length); 430538ee272SAndrey Smirnov } 431538ee272SAndrey Smirnov } 432538ee272SAndrey Smirnov 433538ee272SAndrey Smirnov mutex_unlock(&sp->reply_lock); 434538ee272SAndrey Smirnov } 435538ee272SAndrey Smirnov 436538ee272SAndrey Smirnov static void rave_sp_receive_frame(struct rave_sp *sp, 437538ee272SAndrey Smirnov const unsigned char *data, 438538ee272SAndrey Smirnov size_t length) 439538ee272SAndrey Smirnov { 440538ee272SAndrey Smirnov const size_t checksum_length = sp->variant->checksum->length; 441538ee272SAndrey Smirnov const size_t payload_length = length - checksum_length; 442538ee272SAndrey Smirnov const u8 *crc_reported = &data[payload_length]; 443538ee272SAndrey Smirnov struct device *dev = &sp->serdev->dev; 4447169483cSKyle Spiers u8 crc_calculated[RAVE_SP_CHECKSUM_SIZE]; 4457169483cSKyle Spiers 4467169483cSKyle Spiers if (unlikely(checksum_length > sizeof(crc_calculated))) { 4477169483cSKyle Spiers dev_warn(dev, "Checksum too long, dropping\n"); 4487169483cSKyle Spiers return; 4497169483cSKyle Spiers } 450538ee272SAndrey Smirnov 45144564bc3SAndrey Smirnov print_hex_dump_debug("rave-sp rx: ", DUMP_PREFIX_NONE, 452538ee272SAndrey Smirnov 16, 1, data, length, false); 453538ee272SAndrey Smirnov 454538ee272SAndrey Smirnov if (unlikely(length <= checksum_length)) { 455538ee272SAndrey Smirnov dev_warn(dev, "Dropping short frame\n"); 456538ee272SAndrey Smirnov return; 457538ee272SAndrey Smirnov } 458538ee272SAndrey Smirnov 459538ee272SAndrey Smirnov sp->variant->checksum->subroutine(data, payload_length, 460538ee272SAndrey Smirnov crc_calculated); 461538ee272SAndrey Smirnov 462538ee272SAndrey Smirnov if (memcmp(crc_calculated, crc_reported, checksum_length)) { 463538ee272SAndrey Smirnov dev_warn(dev, "Dropping bad frame\n"); 464538ee272SAndrey Smirnov return; 465538ee272SAndrey Smirnov } 466538ee272SAndrey Smirnov 467538ee272SAndrey Smirnov if (rave_sp_id_is_event(data[0])) 468538ee272SAndrey Smirnov rave_sp_receive_event(sp, data, length); 469538ee272SAndrey Smirnov else 470538ee272SAndrey Smirnov rave_sp_receive_reply(sp, data, length); 471538ee272SAndrey Smirnov } 472538ee272SAndrey Smirnov 473538ee272SAndrey Smirnov static int rave_sp_receive_buf(struct serdev_device *serdev, 474538ee272SAndrey Smirnov const unsigned char *buf, size_t size) 475538ee272SAndrey Smirnov { 476538ee272SAndrey Smirnov struct device *dev = &serdev->dev; 477538ee272SAndrey Smirnov struct rave_sp *sp = dev_get_drvdata(dev); 478538ee272SAndrey Smirnov struct rave_sp_deframer *deframer = &sp->deframer; 479538ee272SAndrey Smirnov const unsigned char *src = buf; 480538ee272SAndrey Smirnov const unsigned char *end = buf + size; 481538ee272SAndrey Smirnov 482538ee272SAndrey Smirnov while (src < end) { 483538ee272SAndrey Smirnov const unsigned char byte = *src++; 484538ee272SAndrey Smirnov 485538ee272SAndrey Smirnov switch (deframer->state) { 486538ee272SAndrey Smirnov case RAVE_SP_EXPECT_SOF: 487538ee272SAndrey Smirnov if (byte == RAVE_SP_STX) 488538ee272SAndrey Smirnov deframer->state = RAVE_SP_EXPECT_DATA; 489538ee272SAndrey Smirnov break; 490538ee272SAndrey Smirnov 491538ee272SAndrey Smirnov case RAVE_SP_EXPECT_DATA: 492538ee272SAndrey Smirnov /* 493538ee272SAndrey Smirnov * Treat special byte values first 494538ee272SAndrey Smirnov */ 495538ee272SAndrey Smirnov switch (byte) { 496538ee272SAndrey Smirnov case RAVE_SP_ETX: 497538ee272SAndrey Smirnov rave_sp_receive_frame(sp, 498538ee272SAndrey Smirnov deframer->data, 499538ee272SAndrey Smirnov deframer->length); 500538ee272SAndrey Smirnov /* 501538ee272SAndrey Smirnov * Once we extracted a complete frame 502538ee272SAndrey Smirnov * out of a stream, we call it done 503538ee272SAndrey Smirnov * and proceed to bailing out while 504538ee272SAndrey Smirnov * resetting the framer to initial 505538ee272SAndrey Smirnov * state, regardless if we've consumed 506538ee272SAndrey Smirnov * all of the stream or not. 507538ee272SAndrey Smirnov */ 508538ee272SAndrey Smirnov goto reset_framer; 509538ee272SAndrey Smirnov case RAVE_SP_STX: 510538ee272SAndrey Smirnov dev_warn(dev, "Bad frame: STX before ETX\n"); 511538ee272SAndrey Smirnov /* 512538ee272SAndrey Smirnov * If we encounter second "start of 513538ee272SAndrey Smirnov * the frame" marker before seeing 514538ee272SAndrey Smirnov * corresponding "end of frame", we 515538ee272SAndrey Smirnov * reset the framer and ignore both: 516538ee272SAndrey Smirnov * frame started by first SOF and 517538ee272SAndrey Smirnov * frame started by current SOF. 518538ee272SAndrey Smirnov * 519538ee272SAndrey Smirnov * NOTE: The above means that only the 520538ee272SAndrey Smirnov * frame started by third SOF, sent 521538ee272SAndrey Smirnov * after this one will have a chance 522538ee272SAndrey Smirnov * to get throught. 523538ee272SAndrey Smirnov */ 524538ee272SAndrey Smirnov goto reset_framer; 525538ee272SAndrey Smirnov case RAVE_SP_DLE: 526538ee272SAndrey Smirnov deframer->state = RAVE_SP_EXPECT_ESCAPED_DATA; 527538ee272SAndrey Smirnov /* 528538ee272SAndrey Smirnov * If we encounter escape sequence we 529538ee272SAndrey Smirnov * need to skip it and collect the 530538ee272SAndrey Smirnov * byte that follows. We do it by 531538ee272SAndrey Smirnov * forcing the next iteration of the 532538ee272SAndrey Smirnov * encompassing while loop. 533538ee272SAndrey Smirnov */ 534538ee272SAndrey Smirnov continue; 535538ee272SAndrey Smirnov } 536538ee272SAndrey Smirnov /* 537538ee272SAndrey Smirnov * For the rest of the bytes, that are not 538538ee272SAndrey Smirnov * speical snoflakes, we do the same thing 539538ee272SAndrey Smirnov * that we do to escaped data - collect it in 540538ee272SAndrey Smirnov * deframer buffer 541538ee272SAndrey Smirnov */ 542538ee272SAndrey Smirnov 543538ee272SAndrey Smirnov /* FALLTHROUGH */ 544538ee272SAndrey Smirnov 545538ee272SAndrey Smirnov case RAVE_SP_EXPECT_ESCAPED_DATA: 546538ee272SAndrey Smirnov if (deframer->length == sizeof(deframer->data)) { 547538ee272SAndrey Smirnov dev_warn(dev, "Bad frame: Too long\n"); 548538ee272SAndrey Smirnov /* 549538ee272SAndrey Smirnov * If the amount of data we've 550538ee272SAndrey Smirnov * accumulated for current frame so 551538ee272SAndrey Smirnov * far starts to exceed the capacity 552538ee272SAndrey Smirnov * of deframer's buffer, there's 553538ee272SAndrey Smirnov * nothing else we can do but to 554538ee272SAndrey Smirnov * discard that data and start 555538ee272SAndrey Smirnov * assemblying a new frame again 556538ee272SAndrey Smirnov */ 557538ee272SAndrey Smirnov goto reset_framer; 558538ee272SAndrey Smirnov } 559538ee272SAndrey Smirnov 5605112cab3SAndrey Smirnov deframer->data[deframer->length++] = byte; 5615112cab3SAndrey Smirnov 562538ee272SAndrey Smirnov /* 563538ee272SAndrey Smirnov * We've extracted out special byte, now we 564538ee272SAndrey Smirnov * can go back to regular data collecting 565538ee272SAndrey Smirnov */ 566538ee272SAndrey Smirnov deframer->state = RAVE_SP_EXPECT_DATA; 567538ee272SAndrey Smirnov break; 568538ee272SAndrey Smirnov } 569538ee272SAndrey Smirnov } 570538ee272SAndrey Smirnov 571538ee272SAndrey Smirnov /* 572538ee272SAndrey Smirnov * The only way to get out of the above loop and end up here 573538ee272SAndrey Smirnov * is throught consuming all of the supplied data, so here we 574538ee272SAndrey Smirnov * report that we processed it all. 575538ee272SAndrey Smirnov */ 576538ee272SAndrey Smirnov return size; 577538ee272SAndrey Smirnov 578538ee272SAndrey Smirnov reset_framer: 579538ee272SAndrey Smirnov /* 580538ee272SAndrey Smirnov * NOTE: A number of codepaths that will drop us here will do 581538ee272SAndrey Smirnov * so before consuming all 'size' bytes of the data passed by 582538ee272SAndrey Smirnov * serdev layer. We rely on the fact that serdev layer will 583538ee272SAndrey Smirnov * re-execute this handler with the remainder of the Rx bytes 584538ee272SAndrey Smirnov * once we report actual number of bytes that we processed. 585538ee272SAndrey Smirnov */ 586538ee272SAndrey Smirnov deframer->state = RAVE_SP_EXPECT_SOF; 587538ee272SAndrey Smirnov deframer->length = 0; 588538ee272SAndrey Smirnov 589538ee272SAndrey Smirnov return src - buf; 590538ee272SAndrey Smirnov } 591538ee272SAndrey Smirnov 592538ee272SAndrey Smirnov static int rave_sp_rdu1_cmd_translate(enum rave_sp_command command) 593538ee272SAndrey Smirnov { 594538ee272SAndrey Smirnov if (command >= RAVE_SP_CMD_STATUS && 595538ee272SAndrey Smirnov command <= RAVE_SP_CMD_CONTROL_EVENTS) 596538ee272SAndrey Smirnov return command; 597538ee272SAndrey Smirnov 598538ee272SAndrey Smirnov return -EINVAL; 599538ee272SAndrey Smirnov } 600538ee272SAndrey Smirnov 601538ee272SAndrey Smirnov static int rave_sp_rdu2_cmd_translate(enum rave_sp_command command) 602538ee272SAndrey Smirnov { 603538ee272SAndrey Smirnov if (command >= RAVE_SP_CMD_GET_FIRMWARE_VERSION && 604538ee272SAndrey Smirnov command <= RAVE_SP_CMD_GET_GPIO_STATE) 605538ee272SAndrey Smirnov return command; 606538ee272SAndrey Smirnov 607538ee272SAndrey Smirnov if (command == RAVE_SP_CMD_REQ_COPPER_REV) { 608538ee272SAndrey Smirnov /* 609538ee272SAndrey Smirnov * As per RDU2 ICD 3.4.47 CMD_GET_COPPER_REV code is 610538ee272SAndrey Smirnov * different from that for RDU1 and it is set to 0x28. 611538ee272SAndrey Smirnov */ 612538ee272SAndrey Smirnov return 0x28; 613538ee272SAndrey Smirnov } 614538ee272SAndrey Smirnov 615538ee272SAndrey Smirnov return rave_sp_rdu1_cmd_translate(command); 616538ee272SAndrey Smirnov } 617538ee272SAndrey Smirnov 618538ee272SAndrey Smirnov static int rave_sp_default_cmd_translate(enum rave_sp_command command) 619538ee272SAndrey Smirnov { 620538ee272SAndrey Smirnov /* 621538ee272SAndrey Smirnov * All of the following command codes were taken from "Table : 622538ee272SAndrey Smirnov * Communications Protocol Message Types" in section 3.3 623538ee272SAndrey Smirnov * "MESSAGE TYPES" of Rave PIC24 ICD. 624538ee272SAndrey Smirnov */ 625538ee272SAndrey Smirnov switch (command) { 626538ee272SAndrey Smirnov case RAVE_SP_CMD_GET_FIRMWARE_VERSION: 627538ee272SAndrey Smirnov return 0x11; 628538ee272SAndrey Smirnov case RAVE_SP_CMD_GET_BOOTLOADER_VERSION: 629538ee272SAndrey Smirnov return 0x12; 630538ee272SAndrey Smirnov case RAVE_SP_CMD_BOOT_SOURCE: 631538ee272SAndrey Smirnov return 0x14; 632538ee272SAndrey Smirnov case RAVE_SP_CMD_SW_WDT: 633538ee272SAndrey Smirnov return 0x1C; 634538ee272SAndrey Smirnov case RAVE_SP_CMD_RESET: 635538ee272SAndrey Smirnov return 0x1E; 636538ee272SAndrey Smirnov case RAVE_SP_CMD_RESET_REASON: 637538ee272SAndrey Smirnov return 0x1F; 638538ee272SAndrey Smirnov default: 639538ee272SAndrey Smirnov return -EINVAL; 640538ee272SAndrey Smirnov } 641538ee272SAndrey Smirnov } 642538ee272SAndrey Smirnov 6436d97b6f1SAndrey Smirnov static const char *devm_rave_sp_version(struct device *dev, 6446d97b6f1SAndrey Smirnov struct rave_sp_version *version) 6456d97b6f1SAndrey Smirnov { 6466d97b6f1SAndrey Smirnov /* 6476d97b6f1SAndrey Smirnov * NOTE: The format string below uses %02d to display u16 6486d97b6f1SAndrey Smirnov * intentionally for the sake of backwards compatibility with 6496d97b6f1SAndrey Smirnov * legacy software. 6506d97b6f1SAndrey Smirnov */ 6516d97b6f1SAndrey Smirnov return devm_kasprintf(dev, GFP_KERNEL, "%02d%02d%02d.%c%c\n", 6526d97b6f1SAndrey Smirnov version->hardware, 6536d97b6f1SAndrey Smirnov le16_to_cpu(version->major), 6546d97b6f1SAndrey Smirnov version->minor, 6556d97b6f1SAndrey Smirnov version->letter[0], 6566d97b6f1SAndrey Smirnov version->letter[1]); 6576d97b6f1SAndrey Smirnov } 6586d97b6f1SAndrey Smirnov 6596d97b6f1SAndrey Smirnov static int rave_sp_get_status(struct rave_sp *sp) 6606d97b6f1SAndrey Smirnov { 6616d97b6f1SAndrey Smirnov struct device *dev = &sp->serdev->dev; 6626d97b6f1SAndrey Smirnov u8 cmd[] = { 6636d97b6f1SAndrey Smirnov [0] = RAVE_SP_CMD_STATUS, 6646d97b6f1SAndrey Smirnov [1] = 0 6656d97b6f1SAndrey Smirnov }; 6666d97b6f1SAndrey Smirnov struct rave_sp_status status; 6676d97b6f1SAndrey Smirnov const char *version; 6686d97b6f1SAndrey Smirnov int ret; 6696d97b6f1SAndrey Smirnov 6706d97b6f1SAndrey Smirnov ret = rave_sp_exec(sp, cmd, sizeof(cmd), &status, sizeof(status)); 6716d97b6f1SAndrey Smirnov if (ret) 6726d97b6f1SAndrey Smirnov return ret; 6736d97b6f1SAndrey Smirnov 6746d97b6f1SAndrey Smirnov version = devm_rave_sp_version(dev, &status.firmware_version); 6756d97b6f1SAndrey Smirnov if (!version) 6766d97b6f1SAndrey Smirnov return -ENOMEM; 6776d97b6f1SAndrey Smirnov 6786d97b6f1SAndrey Smirnov sp->part_number_firmware = version; 6796d97b6f1SAndrey Smirnov 6806d97b6f1SAndrey Smirnov version = devm_rave_sp_version(dev, &status.bootloader_version); 6816d97b6f1SAndrey Smirnov if (!version) 6826d97b6f1SAndrey Smirnov return -ENOMEM; 6836d97b6f1SAndrey Smirnov 6846d97b6f1SAndrey Smirnov sp->part_number_bootloader = version; 6856d97b6f1SAndrey Smirnov 6866d97b6f1SAndrey Smirnov return 0; 6876d97b6f1SAndrey Smirnov } 6886d97b6f1SAndrey Smirnov 689538ee272SAndrey Smirnov static const struct rave_sp_checksum rave_sp_checksum_8b2c = { 690538ee272SAndrey Smirnov .length = 1, 691538ee272SAndrey Smirnov .subroutine = csum_8b2c, 692538ee272SAndrey Smirnov }; 693538ee272SAndrey Smirnov 694538ee272SAndrey Smirnov static const struct rave_sp_checksum rave_sp_checksum_ccitt = { 695538ee272SAndrey Smirnov .length = 2, 696538ee272SAndrey Smirnov .subroutine = csum_ccitt, 697538ee272SAndrey Smirnov }; 698538ee272SAndrey Smirnov 699538ee272SAndrey Smirnov static const struct rave_sp_variant rave_sp_legacy = { 700a6e3bb02SAndrey Smirnov .checksum = &rave_sp_checksum_ccitt, 701538ee272SAndrey Smirnov .cmd = { 702538ee272SAndrey Smirnov .translate = rave_sp_default_cmd_translate, 703538ee272SAndrey Smirnov }, 704538ee272SAndrey Smirnov }; 705538ee272SAndrey Smirnov 706538ee272SAndrey Smirnov static const struct rave_sp_variant rave_sp_rdu1 = { 707538ee272SAndrey Smirnov .checksum = &rave_sp_checksum_8b2c, 708538ee272SAndrey Smirnov .cmd = { 709538ee272SAndrey Smirnov .translate = rave_sp_rdu1_cmd_translate, 710538ee272SAndrey Smirnov }, 711538ee272SAndrey Smirnov }; 712538ee272SAndrey Smirnov 713538ee272SAndrey Smirnov static const struct rave_sp_variant rave_sp_rdu2 = { 714538ee272SAndrey Smirnov .checksum = &rave_sp_checksum_ccitt, 715538ee272SAndrey Smirnov .cmd = { 716538ee272SAndrey Smirnov .translate = rave_sp_rdu2_cmd_translate, 717538ee272SAndrey Smirnov }, 718538ee272SAndrey Smirnov }; 719538ee272SAndrey Smirnov 720538ee272SAndrey Smirnov static const struct of_device_id rave_sp_dt_ids[] = { 721538ee272SAndrey Smirnov { .compatible = "zii,rave-sp-niu", .data = &rave_sp_legacy }, 722538ee272SAndrey Smirnov { .compatible = "zii,rave-sp-mezz", .data = &rave_sp_legacy }, 723538ee272SAndrey Smirnov { .compatible = "zii,rave-sp-esb", .data = &rave_sp_legacy }, 724538ee272SAndrey Smirnov { .compatible = "zii,rave-sp-rdu1", .data = &rave_sp_rdu1 }, 725538ee272SAndrey Smirnov { .compatible = "zii,rave-sp-rdu2", .data = &rave_sp_rdu2 }, 726538ee272SAndrey Smirnov { /* sentinel */ } 727538ee272SAndrey Smirnov }; 728538ee272SAndrey Smirnov 729538ee272SAndrey Smirnov static const struct serdev_device_ops rave_sp_serdev_device_ops = { 730538ee272SAndrey Smirnov .receive_buf = rave_sp_receive_buf, 731538ee272SAndrey Smirnov .write_wakeup = serdev_device_write_wakeup, 732538ee272SAndrey Smirnov }; 733538ee272SAndrey Smirnov 734538ee272SAndrey Smirnov static int rave_sp_probe(struct serdev_device *serdev) 735538ee272SAndrey Smirnov { 736538ee272SAndrey Smirnov struct device *dev = &serdev->dev; 7376d97b6f1SAndrey Smirnov const char *unknown = "unknown\n"; 738538ee272SAndrey Smirnov struct rave_sp *sp; 739538ee272SAndrey Smirnov u32 baud; 740538ee272SAndrey Smirnov int ret; 741538ee272SAndrey Smirnov 742538ee272SAndrey Smirnov if (of_property_read_u32(dev->of_node, "current-speed", &baud)) { 743538ee272SAndrey Smirnov dev_err(dev, 744538ee272SAndrey Smirnov "'current-speed' is not specified in device node\n"); 745538ee272SAndrey Smirnov return -EINVAL; 746538ee272SAndrey Smirnov } 747538ee272SAndrey Smirnov 748538ee272SAndrey Smirnov sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL); 749538ee272SAndrey Smirnov if (!sp) 750538ee272SAndrey Smirnov return -ENOMEM; 751538ee272SAndrey Smirnov 752538ee272SAndrey Smirnov sp->serdev = serdev; 753538ee272SAndrey Smirnov dev_set_drvdata(dev, sp); 754538ee272SAndrey Smirnov 755538ee272SAndrey Smirnov sp->variant = of_device_get_match_data(dev); 756538ee272SAndrey Smirnov if (!sp->variant) 757538ee272SAndrey Smirnov return -ENODEV; 758538ee272SAndrey Smirnov 759538ee272SAndrey Smirnov mutex_init(&sp->bus_lock); 760538ee272SAndrey Smirnov mutex_init(&sp->reply_lock); 761538ee272SAndrey Smirnov BLOCKING_INIT_NOTIFIER_HEAD(&sp->event_notifier_list); 762538ee272SAndrey Smirnov 763538ee272SAndrey Smirnov serdev_device_set_client_ops(serdev, &rave_sp_serdev_device_ops); 764538ee272SAndrey Smirnov ret = devm_serdev_device_open(dev, serdev); 765538ee272SAndrey Smirnov if (ret) 766538ee272SAndrey Smirnov return ret; 767538ee272SAndrey Smirnov 768538ee272SAndrey Smirnov serdev_device_set_baudrate(serdev, baud); 7696c450bdfSAndrey Smirnov serdev_device_set_flow_control(serdev, false); 7706c450bdfSAndrey Smirnov 7716c450bdfSAndrey Smirnov ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE); 7726c450bdfSAndrey Smirnov if (ret) { 7736c450bdfSAndrey Smirnov dev_err(dev, "Failed to set parity\n"); 7746c450bdfSAndrey Smirnov return ret; 7756c450bdfSAndrey Smirnov } 776538ee272SAndrey Smirnov 7776d97b6f1SAndrey Smirnov ret = rave_sp_get_status(sp); 7786d97b6f1SAndrey Smirnov if (ret) { 7796d97b6f1SAndrey Smirnov dev_warn(dev, "Failed to get firmware status: %d\n", ret); 7806d97b6f1SAndrey Smirnov sp->part_number_firmware = unknown; 7816d97b6f1SAndrey Smirnov sp->part_number_bootloader = unknown; 7826d97b6f1SAndrey Smirnov } 7836d97b6f1SAndrey Smirnov 7846d97b6f1SAndrey Smirnov /* 7856d97b6f1SAndrey Smirnov * Those strings already have a \n embedded, so there's no 7866d97b6f1SAndrey Smirnov * need to have one in format string. 7876d97b6f1SAndrey Smirnov */ 7886d97b6f1SAndrey Smirnov dev_info(dev, "Firmware version: %s", sp->part_number_firmware); 7896d97b6f1SAndrey Smirnov dev_info(dev, "Bootloader version: %s", sp->part_number_bootloader); 7906d97b6f1SAndrey Smirnov 791538ee272SAndrey Smirnov return devm_of_platform_populate(dev); 792538ee272SAndrey Smirnov } 793538ee272SAndrey Smirnov 794538ee272SAndrey Smirnov MODULE_DEVICE_TABLE(of, rave_sp_dt_ids); 795538ee272SAndrey Smirnov 796538ee272SAndrey Smirnov static struct serdev_device_driver rave_sp_drv = { 797538ee272SAndrey Smirnov .probe = rave_sp_probe, 798538ee272SAndrey Smirnov .driver = { 799538ee272SAndrey Smirnov .name = "rave-sp", 800538ee272SAndrey Smirnov .of_match_table = rave_sp_dt_ids, 801538ee272SAndrey Smirnov }, 802538ee272SAndrey Smirnov }; 803538ee272SAndrey Smirnov module_serdev_device_driver(rave_sp_drv); 804538ee272SAndrey Smirnov 805538ee272SAndrey Smirnov MODULE_LICENSE("GPL"); 806538ee272SAndrey Smirnov MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>"); 807538ee272SAndrey Smirnov MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>"); 808538ee272SAndrey Smirnov MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>"); 809538ee272SAndrey Smirnov MODULE_DESCRIPTION("RAVE SP core driver"); 810