linux/drivers/nfc/fdp/fdp.c
<<
>>
Prefs
   1/* -------------------------------------------------------------------------
   2 * Copyright (C) 2014-2016, Intel Corporation
   3 *
   4 *  This program is free software; you can redistribute it and/or modify
   5 *  it under the terms of the GNU General Public License as published by
   6 *  the Free Software Foundation; either version 2 of the License, or
   7 *  (at your option) any later version.
   8 *
   9 *  This program is distributed in the hope that it will be useful,
  10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 *  GNU General Public License for more details.
  13 * -------------------------------------------------------------------------
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/nfc.h>
  18#include <linux/i2c.h>
  19#include <linux/delay.h>
  20#include <linux/firmware.h>
  21#include <net/nfc/nci_core.h>
  22
  23#include "fdp.h"
  24
  25#define FDP_OTP_PATCH_NAME                      "otp.bin"
  26#define FDP_RAM_PATCH_NAME                      "ram.bin"
  27#define FDP_FW_HEADER_SIZE                      576
  28#define FDP_FW_UPDATE_SLEEP                     1000
  29
  30#define NCI_GET_VERSION_TIMEOUT                 8000
  31#define NCI_PATCH_REQUEST_TIMEOUT               8000
  32#define FDP_PATCH_CONN_DEST                     0xC2
  33#define FDP_PATCH_CONN_PARAM_TYPE               0xA0
  34
  35#define NCI_PATCH_TYPE_RAM                      0x00
  36#define NCI_PATCH_TYPE_OTP                      0x01
  37#define NCI_PATCH_TYPE_EOT                      0xFF
  38
  39#define NCI_PARAM_ID_FW_RAM_VERSION             0xA0
  40#define NCI_PARAM_ID_FW_OTP_VERSION             0xA1
  41#define NCI_PARAM_ID_OTP_LIMITED_VERSION        0xC5
  42#define NCI_PARAM_ID_KEY_INDEX_ID               0xC6
  43
  44#define NCI_GID_PROP                            0x0F
  45#define NCI_OP_PROP_PATCH_OID                   0x08
  46#define NCI_OP_PROP_SET_PDATA_OID               0x23
  47
  48struct fdp_nci_info {
  49        struct nfc_phy_ops *phy_ops;
  50        struct fdp_i2c_phy *phy;
  51        struct nci_dev *ndev;
  52
  53        const struct firmware *otp_patch;
  54        const struct firmware *ram_patch;
  55        u32 otp_patch_version;
  56        u32 ram_patch_version;
  57
  58        u32 otp_version;
  59        u32 ram_version;
  60        u32 limited_otp_version;
  61        u8 key_index;
  62
  63        u8 *fw_vsc_cfg;
  64        u8 clock_type;
  65        u32 clock_freq;
  66
  67        atomic_t data_pkt_counter;
  68        void (*data_pkt_counter_cb)(struct nci_dev *ndev);
  69        u8 setup_patch_sent;
  70        u8 setup_patch_ntf;
  71        u8 setup_patch_status;
  72        u8 setup_reset_ntf;
  73        wait_queue_head_t setup_wq;
  74};
  75
  76static u8 nci_core_get_config_otp_ram_version[5] = {
  77        0x04,
  78        NCI_PARAM_ID_FW_RAM_VERSION,
  79        NCI_PARAM_ID_FW_OTP_VERSION,
  80        NCI_PARAM_ID_OTP_LIMITED_VERSION,
  81        NCI_PARAM_ID_KEY_INDEX_ID
  82};
  83
  84struct nci_core_get_config_rsp {
  85        u8 status;
  86        u8 count;
  87        u8 data[0];
  88};
  89
  90static int fdp_nci_create_conn(struct nci_dev *ndev)
  91{
  92        struct fdp_nci_info *info = nci_get_drvdata(ndev);
  93        struct core_conn_create_dest_spec_params param;
  94        int r;
  95
  96        /* proprietary destination specific paramerer without value */
  97        param.type = FDP_PATCH_CONN_PARAM_TYPE;
  98        param.length = 0x00;
  99
 100        r = nci_core_conn_create(info->ndev, FDP_PATCH_CONN_DEST, 1,
 101                                 sizeof(param), &param);
 102        if (r)
 103                return r;
 104
 105        return nci_get_conn_info_by_dest_type_params(ndev,
 106                                                     FDP_PATCH_CONN_DEST, NULL);
 107}
 108
 109static inline int fdp_nci_get_versions(struct nci_dev *ndev)
 110{
 111        return nci_core_cmd(ndev, NCI_OP_CORE_GET_CONFIG_CMD,
 112                            sizeof(nci_core_get_config_otp_ram_version),
 113                            (__u8 *) &nci_core_get_config_otp_ram_version);
 114}
 115
 116static inline int fdp_nci_patch_cmd(struct nci_dev *ndev, u8 type)
 117{
 118        return nci_prop_cmd(ndev, NCI_OP_PROP_PATCH_OID, sizeof(type), &type);
 119}
 120
 121static inline int fdp_nci_set_production_data(struct nci_dev *ndev, u8 len,
 122                                              char *data)
 123{
 124        return nci_prop_cmd(ndev, NCI_OP_PROP_SET_PDATA_OID, len, data);
 125}
 126
 127static int fdp_nci_set_clock(struct nci_dev *ndev, u8 clock_type,
 128                             u32 clock_freq)
 129{
 130        u32 fc = 13560;
 131        u32 nd, num, delta;
 132        char data[9];
 133
 134        nd = (24 * fc) / clock_freq;
 135        delta = 24 * fc - nd * clock_freq;
 136        num = (32768 * delta) / clock_freq;
 137
 138        data[0] = 0x00;
 139        data[1] = 0x00;
 140        data[2] = 0x00;
 141
 142        data[3] = 0x10;
 143        data[4] = 0x04;
 144        data[5] = num & 0xFF;
 145        data[6] = (num >> 8) & 0xff;
 146        data[7] = nd;
 147        data[8] = clock_type;
 148
 149        return fdp_nci_set_production_data(ndev, 9, data);
 150}
 151
 152static void fdp_nci_send_patch_cb(struct nci_dev *ndev)
 153{
 154        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 155
 156        info->setup_patch_sent = 1;
 157        wake_up(&info->setup_wq);
 158}
 159
 160/**
 161 * Register a packet sent counter and a callback
 162 *
 163 * We have no other way of knowing when all firmware packets were sent out
 164 * on the i2c bus. We need to know that in order to close the connection and
 165 * send the patch end message.
 166 */
 167static void fdp_nci_set_data_pkt_counter(struct nci_dev *ndev,
 168                                  void (*cb)(struct nci_dev *ndev), int count)
 169{
 170        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 171        struct device *dev = &info->phy->i2c_dev->dev;
 172
 173        dev_dbg(dev, "NCI data pkt counter %d\n", count);
 174        atomic_set(&info->data_pkt_counter, count);
 175        info->data_pkt_counter_cb = cb;
 176}
 177
 178/**
 179 * The device is expecting a stream of packets. All packets need to
 180 * have the PBF flag set to 0x0 (last packet) even if the firmware
 181 * file is segmented and there are multiple packets. If we give the
 182 * whole firmware to nci_send_data it will segment it and it will set
 183 * the PBF flag to 0x01 so we need to do the segmentation here.
 184 *
 185 * The firmware will be analyzed and applied when we send NCI_OP_PROP_PATCH_CMD
 186 * command with NCI_PATCH_TYPE_EOT parameter. The device will send a
 187 * NFCC_PATCH_NTF packaet and a NCI_OP_CORE_RESET_NTF packet.
 188 */
 189static int fdp_nci_send_patch(struct nci_dev *ndev, u8 conn_id, u8 type)
 190{
 191        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 192        const struct firmware *fw;
 193        struct sk_buff *skb;
 194        unsigned long len;
 195        u8 max_size, payload_size;
 196        int rc = 0;
 197
 198        if ((type == NCI_PATCH_TYPE_OTP && !info->otp_patch) ||
 199            (type == NCI_PATCH_TYPE_RAM && !info->ram_patch))
 200                return -EINVAL;
 201
 202        if (type == NCI_PATCH_TYPE_OTP)
 203                fw = info->otp_patch;
 204        else
 205                fw = info->ram_patch;
 206
 207        max_size = nci_conn_max_data_pkt_payload_size(ndev, conn_id);
 208        if (max_size <= 0)
 209                return -EINVAL;
 210
 211        len = fw->size;
 212
 213        fdp_nci_set_data_pkt_counter(ndev, fdp_nci_send_patch_cb,
 214                                     DIV_ROUND_UP(fw->size, max_size));
 215
 216        while (len) {
 217
 218                payload_size = min_t(unsigned long, (unsigned long) max_size,
 219                                     len);
 220
 221                skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + payload_size),
 222                                    GFP_KERNEL);
 223                if (!skb) {
 224                        fdp_nci_set_data_pkt_counter(ndev, NULL, 0);
 225                        return -ENOMEM;
 226                }
 227
 228
 229                skb_reserve(skb, NCI_CTRL_HDR_SIZE);
 230
 231                memcpy(skb_put(skb, payload_size), fw->data + (fw->size - len),
 232                       payload_size);
 233
 234                rc = nci_send_data(ndev, conn_id, skb);
 235
 236                if (rc) {
 237                        fdp_nci_set_data_pkt_counter(ndev, NULL, 0);
 238                        return rc;
 239                }
 240
 241                len -= payload_size;
 242        }
 243
 244        return rc;
 245}
 246
 247static int fdp_nci_open(struct nci_dev *ndev)
 248{
 249        int r;
 250        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 251        struct device *dev = &info->phy->i2c_dev->dev;
 252
 253        dev_dbg(dev, "%s\n", __func__);
 254
 255        r = info->phy_ops->enable(info->phy);
 256
 257        return r;
 258}
 259
 260static int fdp_nci_close(struct nci_dev *ndev)
 261{
 262        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 263        struct device *dev = &info->phy->i2c_dev->dev;
 264
 265        dev_dbg(dev, "%s\n", __func__);
 266        return 0;
 267}
 268
 269static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
 270{
 271        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 272        struct device *dev = &info->phy->i2c_dev->dev;
 273
 274        dev_dbg(dev, "%s\n", __func__);
 275
 276        if (atomic_dec_and_test(&info->data_pkt_counter))
 277                info->data_pkt_counter_cb(ndev);
 278
 279        return info->phy_ops->write(info->phy, skb);
 280}
 281
 282int fdp_nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb)
 283{
 284        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 285        struct device *dev = &info->phy->i2c_dev->dev;
 286
 287        dev_dbg(dev, "%s\n", __func__);
 288        return nci_recv_frame(ndev, skb);
 289}
 290EXPORT_SYMBOL(fdp_nci_recv_frame);
 291
 292static int fdp_nci_request_firmware(struct nci_dev *ndev)
 293{
 294        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 295        struct device *dev = &info->phy->i2c_dev->dev;
 296        u8 *data;
 297        int r;
 298
 299        r = request_firmware(&info->ram_patch, FDP_RAM_PATCH_NAME, dev);
 300        if (r < 0) {
 301                nfc_err(dev, "RAM patch request error\n");
 302                goto error;
 303        }
 304
 305        data = (u8 *) info->ram_patch->data;
 306        info->ram_patch_version =
 307                data[FDP_FW_HEADER_SIZE] |
 308                (data[FDP_FW_HEADER_SIZE + 1] << 8) |
 309                (data[FDP_FW_HEADER_SIZE + 2] << 16) |
 310                (data[FDP_FW_HEADER_SIZE + 3] << 24);
 311
 312        dev_dbg(dev, "RAM patch version: %d, size: %d\n",
 313                  info->ram_patch_version, (int) info->ram_patch->size);
 314
 315
 316        r = request_firmware(&info->otp_patch, FDP_OTP_PATCH_NAME, dev);
 317        if (r < 0) {
 318                nfc_err(dev, "OTP patch request error\n");
 319                goto out;
 320        }
 321
 322        data = (u8 *) info->otp_patch->data;
 323        info->otp_patch_version =
 324                data[FDP_FW_HEADER_SIZE] |
 325                (data[FDP_FW_HEADER_SIZE + 1] << 8) |
 326                (data[FDP_FW_HEADER_SIZE+2] << 16) |
 327                (data[FDP_FW_HEADER_SIZE+3] << 24);
 328
 329        dev_dbg(dev, "OTP patch version: %d, size: %d\n",
 330                 info->otp_patch_version, (int) info->otp_patch->size);
 331out:
 332        return 0;
 333error:
 334        return r;
 335}
 336
 337static void fdp_nci_release_firmware(struct nci_dev *ndev)
 338{
 339        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 340
 341        if (info->otp_patch) {
 342                release_firmware(info->otp_patch);
 343                info->otp_patch = NULL;
 344        }
 345
 346        if (info->ram_patch) {
 347                release_firmware(info->ram_patch);
 348                info->ram_patch = NULL;
 349        }
 350}
 351
 352static int fdp_nci_patch_otp(struct nci_dev *ndev)
 353{
 354        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 355        struct device *dev = &info->phy->i2c_dev->dev;
 356        int conn_id;
 357        int r = 0;
 358
 359        if (info->otp_version >= info->otp_patch_version)
 360                goto out;
 361
 362        info->setup_patch_sent = 0;
 363        info->setup_reset_ntf = 0;
 364        info->setup_patch_ntf = 0;
 365
 366        /* Patch init request */
 367        r = fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_OTP);
 368        if (r)
 369                goto out;
 370
 371        /* Patch data connection creation */
 372        conn_id = fdp_nci_create_conn(ndev);
 373        if (conn_id < 0) {
 374                r = conn_id;
 375                goto out;
 376        }
 377
 378        /* Send the patch over the data connection */
 379        r = fdp_nci_send_patch(ndev, conn_id, NCI_PATCH_TYPE_OTP);
 380        if (r)
 381                goto out;
 382
 383        /* Wait for all the packets to be send over i2c */
 384        wait_event_interruptible(info->setup_wq,
 385                                 info->setup_patch_sent == 1);
 386
 387        /* make sure that the NFCC processed the last data packet */
 388        msleep(FDP_FW_UPDATE_SLEEP);
 389
 390        /* Close the data connection */
 391        r = nci_core_conn_close(info->ndev, conn_id);
 392        if (r)
 393                goto out;
 394
 395        /* Patch finish message */
 396        if (fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_EOT)) {
 397                nfc_err(dev, "OTP patch error 0x%x\n", r);
 398                r = -EINVAL;
 399                goto out;
 400        }
 401
 402        /* If the patch notification didn't arrive yet, wait for it */
 403        wait_event_interruptible(info->setup_wq, info->setup_patch_ntf);
 404
 405        /* Check if the patching was successful */
 406        r = info->setup_patch_status;
 407        if (r) {
 408                nfc_err(dev, "OTP patch error 0x%x\n", r);
 409                r = -EINVAL;
 410                goto out;
 411        }
 412
 413        /*
 414         * We need to wait for the reset notification before we
 415         * can continue
 416         */
 417        wait_event_interruptible(info->setup_wq, info->setup_reset_ntf);
 418
 419out:
 420        return r;
 421}
 422
 423static int fdp_nci_patch_ram(struct nci_dev *ndev)
 424{
 425        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 426        struct device *dev = &info->phy->i2c_dev->dev;
 427        int conn_id;
 428        int r = 0;
 429
 430        if (info->ram_version >= info->ram_patch_version)
 431                goto out;
 432
 433        info->setup_patch_sent = 0;
 434        info->setup_reset_ntf = 0;
 435        info->setup_patch_ntf = 0;
 436
 437        /* Patch init request */
 438        r = fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_RAM);
 439        if (r)
 440                goto out;
 441
 442        /* Patch data connection creation */
 443        conn_id = fdp_nci_create_conn(ndev);
 444        if (conn_id < 0) {
 445                r = conn_id;
 446                goto out;
 447        }
 448
 449        /* Send the patch over the data connection */
 450        r = fdp_nci_send_patch(ndev, conn_id, NCI_PATCH_TYPE_RAM);
 451        if (r)
 452                goto out;
 453
 454        /* Wait for all the packets to be send over i2c */
 455        wait_event_interruptible(info->setup_wq,
 456                                 info->setup_patch_sent == 1);
 457
 458        /* make sure that the NFCC processed the last data packet */
 459        msleep(FDP_FW_UPDATE_SLEEP);
 460
 461        /* Close the data connection */
 462        r = nci_core_conn_close(info->ndev, conn_id);
 463        if (r)
 464                goto out;
 465
 466        /* Patch finish message */
 467        if (fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_EOT)) {
 468                nfc_err(dev, "RAM patch error 0x%x\n", r);
 469                r = -EINVAL;
 470                goto out;
 471        }
 472
 473        /* If the patch notification didn't arrive yet, wait for it */
 474        wait_event_interruptible(info->setup_wq, info->setup_patch_ntf);
 475
 476        /* Check if the patching was successful */
 477        r = info->setup_patch_status;
 478        if (r) {
 479                nfc_err(dev, "RAM patch error 0x%x\n", r);
 480                r = -EINVAL;
 481                goto out;
 482        }
 483
 484        /*
 485         * We need to wait for the reset notification before we
 486         * can continue
 487         */
 488        wait_event_interruptible(info->setup_wq, info->setup_reset_ntf);
 489
 490out:
 491        return r;
 492}
 493
 494static int fdp_nci_setup(struct nci_dev *ndev)
 495{
 496        /* Format: total length followed by an NCI packet */
 497        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 498        struct device *dev = &info->phy->i2c_dev->dev;
 499        int r;
 500        u8 patched = 0;
 501
 502        dev_dbg(dev, "%s\n", __func__);
 503
 504        r = nci_core_init(ndev);
 505        if (r)
 506                goto error;
 507
 508        /* Get RAM and OTP version */
 509        r = fdp_nci_get_versions(ndev);
 510        if (r)
 511                goto error;
 512
 513        /* Load firmware from disk */
 514        r = fdp_nci_request_firmware(ndev);
 515        if (r)
 516                goto error;
 517
 518        /* Update OTP */
 519        if (info->otp_version < info->otp_patch_version) {
 520                r = fdp_nci_patch_otp(ndev);
 521                if (r)
 522                        goto error;
 523                patched = 1;
 524        }
 525
 526        /* Update RAM */
 527        if (info->ram_version < info->ram_patch_version) {
 528                r = fdp_nci_patch_ram(ndev);
 529                if (r)
 530                        goto error;
 531                patched = 1;
 532        }
 533
 534        /* Release the firmware buffers */
 535        fdp_nci_release_firmware(ndev);
 536
 537        /* If a patch was applied the new version is checked */
 538        if (patched) {
 539                r = nci_core_init(ndev);
 540                if (r)
 541                        goto error;
 542
 543                r = fdp_nci_get_versions(ndev);
 544                if (r)
 545                        goto error;
 546
 547                if (info->otp_version != info->otp_patch_version ||
 548                    info->ram_version != info->ram_patch_version) {
 549                        nfc_err(dev, "Firmware update failed");
 550                        r = -EINVAL;
 551                        goto error;
 552                }
 553        }
 554
 555        /*
 556         * We initialized the devices but the NFC subsystem expects
 557         * it to not be initialized.
 558         */
 559        return nci_core_reset(ndev);
 560
 561error:
 562        fdp_nci_release_firmware(ndev);
 563        nfc_err(dev, "Setup error %d\n", r);
 564        return r;
 565}
 566
 567static int fdp_nci_post_setup(struct nci_dev *ndev)
 568{
 569        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 570        struct device *dev = &info->phy->i2c_dev->dev;
 571        int r;
 572
 573        /* Check if the device has VSC */
 574        if (info->fw_vsc_cfg && info->fw_vsc_cfg[0]) {
 575
 576                /* Set the vendor specific configuration */
 577                r = fdp_nci_set_production_data(ndev, info->fw_vsc_cfg[3],
 578                                                &info->fw_vsc_cfg[4]);
 579                if (r) {
 580                        nfc_err(dev, "Vendor specific config set error %d\n",
 581                                r);
 582                        return r;
 583                }
 584        }
 585
 586        /* Set clock type and frequency */
 587        r = fdp_nci_set_clock(ndev, info->clock_type, info->clock_freq);
 588        if (r) {
 589                nfc_err(dev, "Clock set error %d\n", r);
 590                return r;
 591        }
 592
 593        /*
 594         * In order to apply the VSC FDP needs a reset
 595         */
 596        r = nci_core_reset(ndev);
 597        if (r)
 598                return r;
 599
 600        /**
 601         * The nci core was initialized when post setup was called
 602         * so we leave it like that
 603         */
 604        return nci_core_init(ndev);
 605}
 606
 607static int fdp_nci_core_reset_ntf_packet(struct nci_dev *ndev,
 608                                          struct sk_buff *skb)
 609{
 610        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 611        struct device *dev = &info->phy->i2c_dev->dev;
 612
 613        dev_dbg(dev, "%s\n", __func__);
 614        info->setup_reset_ntf = 1;
 615        wake_up(&info->setup_wq);
 616
 617        return 0;
 618}
 619
 620static int fdp_nci_prop_patch_ntf_packet(struct nci_dev *ndev,
 621                                          struct sk_buff *skb)
 622{
 623        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 624        struct device *dev = &info->phy->i2c_dev->dev;
 625
 626        dev_dbg(dev, "%s\n", __func__);
 627        info->setup_patch_ntf = 1;
 628        info->setup_patch_status = skb->data[0];
 629        wake_up(&info->setup_wq);
 630
 631        return 0;
 632}
 633
 634static int fdp_nci_prop_patch_rsp_packet(struct nci_dev *ndev,
 635                                          struct sk_buff *skb)
 636{
 637        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 638        struct device *dev = &info->phy->i2c_dev->dev;
 639        u8 status = skb->data[0];
 640
 641        dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
 642        nci_req_complete(ndev, status);
 643
 644        return 0;
 645}
 646
 647static int fdp_nci_prop_set_production_data_rsp_packet(struct nci_dev *ndev,
 648                                                        struct sk_buff *skb)
 649{
 650        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 651        struct device *dev = &info->phy->i2c_dev->dev;
 652        u8 status = skb->data[0];
 653
 654        dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
 655        nci_req_complete(ndev, status);
 656
 657        return 0;
 658}
 659
 660static int fdp_nci_core_get_config_rsp_packet(struct nci_dev *ndev,
 661                                                struct sk_buff *skb)
 662{
 663        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 664        struct device *dev = &info->phy->i2c_dev->dev;
 665        struct nci_core_get_config_rsp *rsp = (void *) skb->data;
 666        u8 i, *p;
 667
 668        if (rsp->status == NCI_STATUS_OK) {
 669
 670                p = rsp->data;
 671                for (i = 0; i < 4; i++) {
 672
 673                        switch (*p++) {
 674                        case NCI_PARAM_ID_FW_RAM_VERSION:
 675                                p++;
 676                                info->ram_version = le32_to_cpup((__le32 *) p);
 677                                p += 4;
 678                                break;
 679                        case NCI_PARAM_ID_FW_OTP_VERSION:
 680                                p++;
 681                                info->otp_version = le32_to_cpup((__le32 *) p);
 682                                p += 4;
 683                                break;
 684                        case NCI_PARAM_ID_OTP_LIMITED_VERSION:
 685                                p++;
 686                                info->otp_version = le32_to_cpup((__le32 *) p);
 687                                p += 4;
 688                                break;
 689                        case NCI_PARAM_ID_KEY_INDEX_ID:
 690                                p++;
 691                                info->key_index = *p++;
 692                        }
 693                }
 694        }
 695
 696        dev_dbg(dev, "OTP version %d\n", info->otp_version);
 697        dev_dbg(dev, "RAM version %d\n", info->ram_version);
 698        dev_dbg(dev, "key index %d\n", info->key_index);
 699        dev_dbg(dev, "%s: status 0x%x\n", __func__, rsp->status);
 700
 701        nci_req_complete(ndev, rsp->status);
 702
 703        return 0;
 704}
 705
 706static struct nci_driver_ops fdp_core_ops[] = {
 707        {
 708                .opcode = NCI_OP_CORE_GET_CONFIG_RSP,
 709                .rsp = fdp_nci_core_get_config_rsp_packet,
 710        },
 711        {
 712                .opcode = NCI_OP_CORE_RESET_NTF,
 713                .ntf = fdp_nci_core_reset_ntf_packet,
 714        },
 715};
 716
 717static struct nci_driver_ops fdp_prop_ops[] = {
 718        {
 719                .opcode = nci_opcode_pack(NCI_GID_PROP, NCI_OP_PROP_PATCH_OID),
 720                .rsp = fdp_nci_prop_patch_rsp_packet,
 721                .ntf = fdp_nci_prop_patch_ntf_packet,
 722        },
 723        {
 724                .opcode = nci_opcode_pack(NCI_GID_PROP,
 725                                          NCI_OP_PROP_SET_PDATA_OID),
 726                .rsp = fdp_nci_prop_set_production_data_rsp_packet,
 727        },
 728};
 729
 730struct nci_ops nci_ops = {
 731        .open = fdp_nci_open,
 732        .close = fdp_nci_close,
 733        .send = fdp_nci_send,
 734        .setup = fdp_nci_setup,
 735        .post_setup = fdp_nci_post_setup,
 736        .prop_ops = fdp_prop_ops,
 737        .n_prop_ops = ARRAY_SIZE(fdp_prop_ops),
 738        .core_ops = fdp_core_ops,
 739        .n_core_ops = ARRAY_SIZE(fdp_core_ops),
 740};
 741
 742int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops,
 743                        struct nci_dev **ndevp, int tx_headroom,
 744                        int tx_tailroom, u8 clock_type, u32 clock_freq,
 745                        u8 *fw_vsc_cfg)
 746{
 747        struct device *dev = &phy->i2c_dev->dev;
 748        struct fdp_nci_info *info;
 749        struct nci_dev *ndev;
 750        u32 protocols;
 751        int r;
 752
 753        info = kzalloc(sizeof(struct fdp_nci_info), GFP_KERNEL);
 754        if (!info) {
 755                r = -ENOMEM;
 756                goto err_info_alloc;
 757        }
 758
 759        info->phy = phy;
 760        info->phy_ops = phy_ops;
 761        info->clock_type = clock_type;
 762        info->clock_freq = clock_freq;
 763        info->fw_vsc_cfg = fw_vsc_cfg;
 764
 765        init_waitqueue_head(&info->setup_wq);
 766
 767        protocols = NFC_PROTO_JEWEL_MASK |
 768                    NFC_PROTO_MIFARE_MASK |
 769                    NFC_PROTO_FELICA_MASK |
 770                    NFC_PROTO_ISO14443_MASK |
 771                    NFC_PROTO_ISO14443_B_MASK |
 772                    NFC_PROTO_NFC_DEP_MASK |
 773                    NFC_PROTO_ISO15693_MASK;
 774
 775        ndev = nci_allocate_device(&nci_ops, protocols, tx_headroom,
 776                                   tx_tailroom);
 777        if (!ndev) {
 778                nfc_err(dev, "Cannot allocate nfc ndev\n");
 779                r = -ENOMEM;
 780                goto err_alloc_ndev;
 781        }
 782
 783        r = nci_register_device(ndev);
 784        if (r)
 785                goto err_regdev;
 786
 787        *ndevp = ndev;
 788        info->ndev = ndev;
 789
 790        nci_set_drvdata(ndev, info);
 791
 792        return 0;
 793
 794err_regdev:
 795        nci_free_device(ndev);
 796err_alloc_ndev:
 797        kfree(info);
 798err_info_alloc:
 799        return r;
 800}
 801EXPORT_SYMBOL(fdp_nci_probe);
 802
 803void fdp_nci_remove(struct nci_dev *ndev)
 804{
 805        struct fdp_nci_info *info = nci_get_drvdata(ndev);
 806        struct device *dev = &info->phy->i2c_dev->dev;
 807
 808        dev_dbg(dev, "%s\n", __func__);
 809
 810        nci_unregister_device(ndev);
 811        nci_free_device(ndev);
 812        kfree(info);
 813}
 814EXPORT_SYMBOL(fdp_nci_remove);
 815
 816MODULE_LICENSE("GPL");
 817MODULE_DESCRIPTION("NFC NCI driver for Intel Fields Peak NFC controller");
 818MODULE_AUTHOR("Robert Dolca <robert.dolca@intel.com>");
 819