root/drivers/nfc/nfcmrvl/i2c.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nfcmrvl_i2c_read
  2. nfcmrvl_i2c_int_irq_thread_fn
  3. nfcmrvl_i2c_nci_open
  4. nfcmrvl_i2c_nci_close
  5. nfcmrvl_i2c_nci_send
  6. nfcmrvl_i2c_nci_update_config
  7. nfcmrvl_i2c_parse_dt
  8. nfcmrvl_i2c_probe
  9. nfcmrvl_i2c_remove

   1 /**
   2  * Marvell NFC-over-I2C driver: I2C interface related functions
   3  *
   4  * Copyright (C) 2015, Marvell International Ltd.
   5  *
   6  * This software file (the "File") is distributed by Marvell International
   7  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
   8  * (the "License").  You may use, redistribute and/or modify this File in
   9  * accordance with the terms and conditions of the License, a copy of which
  10  * is available on the worldwide web at
  11  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  12  *
  13  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  14  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  15  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
  16  * this warranty disclaimer.
  17  **/
  18 
  19 #include <linux/module.h>
  20 #include <linux/interrupt.h>
  21 #include <linux/i2c.h>
  22 #include <linux/pm_runtime.h>
  23 #include <linux/nfc.h>
  24 #include <linux/gpio.h>
  25 #include <linux/delay.h>
  26 #include <linux/of_irq.h>
  27 #include <linux/of_gpio.h>
  28 #include <net/nfc/nci.h>
  29 #include <net/nfc/nci_core.h>
  30 #include "nfcmrvl.h"
  31 
  32 struct nfcmrvl_i2c_drv_data {
  33         unsigned long flags;
  34         struct device *dev;
  35         struct i2c_client *i2c;
  36         struct nfcmrvl_private *priv;
  37 };
  38 
  39 static int nfcmrvl_i2c_read(struct nfcmrvl_i2c_drv_data *drv_data,
  40                             struct sk_buff **skb)
  41 {
  42         int ret;
  43         struct nci_ctrl_hdr nci_hdr;
  44 
  45         /* Read NCI header to know the payload size */
  46         ret = i2c_master_recv(drv_data->i2c, (u8 *)&nci_hdr, NCI_CTRL_HDR_SIZE);
  47         if (ret != NCI_CTRL_HDR_SIZE) {
  48                 nfc_err(&drv_data->i2c->dev, "cannot read NCI header\n");
  49                 return -EBADMSG;
  50         }
  51 
  52         if (nci_hdr.plen > NCI_MAX_PAYLOAD_SIZE) {
  53                 nfc_err(&drv_data->i2c->dev, "invalid packet payload size\n");
  54                 return -EBADMSG;
  55         }
  56 
  57         *skb = nci_skb_alloc(drv_data->priv->ndev,
  58                              nci_hdr.plen + NCI_CTRL_HDR_SIZE, GFP_KERNEL);
  59         if (!*skb)
  60                 return -ENOMEM;
  61 
  62         /* Copy NCI header into the SKB */
  63         skb_put_data(*skb, &nci_hdr, NCI_CTRL_HDR_SIZE);
  64 
  65         if (nci_hdr.plen) {
  66                 /* Read the NCI payload */
  67                 ret = i2c_master_recv(drv_data->i2c,
  68                                       skb_put(*skb, nci_hdr.plen),
  69                                       nci_hdr.plen);
  70 
  71                 if (ret != nci_hdr.plen) {
  72                         nfc_err(&drv_data->i2c->dev,
  73                                 "Invalid frame payload length: %u (expected %u)\n",
  74                                 ret, nci_hdr.plen);
  75                         kfree_skb(*skb);
  76                         return -EBADMSG;
  77                 }
  78         }
  79 
  80         return 0;
  81 }
  82 
  83 static irqreturn_t nfcmrvl_i2c_int_irq_thread_fn(int irq, void *drv_data_ptr)
  84 {
  85         struct nfcmrvl_i2c_drv_data *drv_data = drv_data_ptr;
  86         struct sk_buff *skb = NULL;
  87         int ret;
  88 
  89         if (!drv_data->priv)
  90                 return IRQ_HANDLED;
  91 
  92         if (test_bit(NFCMRVL_PHY_ERROR, &drv_data->priv->flags))
  93                 return IRQ_HANDLED;
  94 
  95         ret = nfcmrvl_i2c_read(drv_data, &skb);
  96 
  97         switch (ret) {
  98         case -EREMOTEIO:
  99                 set_bit(NFCMRVL_PHY_ERROR, &drv_data->priv->flags);
 100                 break;
 101         case -ENOMEM:
 102         case -EBADMSG:
 103                 nfc_err(&drv_data->i2c->dev, "read failed %d\n", ret);
 104                 break;
 105         default:
 106                 if (nfcmrvl_nci_recv_frame(drv_data->priv, skb) < 0)
 107                         nfc_err(&drv_data->i2c->dev, "corrupted RX packet\n");
 108                 break;
 109         }
 110         return IRQ_HANDLED;
 111 }
 112 
 113 static int nfcmrvl_i2c_nci_open(struct nfcmrvl_private *priv)
 114 {
 115         struct nfcmrvl_i2c_drv_data *drv_data = priv->drv_data;
 116 
 117         if (!drv_data)
 118                 return -ENODEV;
 119 
 120         return 0;
 121 }
 122 
 123 static int nfcmrvl_i2c_nci_close(struct nfcmrvl_private *priv)
 124 {
 125         return 0;
 126 }
 127 
 128 static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
 129                                 struct sk_buff *skb)
 130 {
 131         struct nfcmrvl_i2c_drv_data *drv_data = priv->drv_data;
 132         int ret;
 133 
 134         if (test_bit(NFCMRVL_PHY_ERROR, &priv->flags))
 135                 return -EREMOTEIO;
 136 
 137         ret = i2c_master_send(drv_data->i2c, skb->data, skb->len);
 138 
 139         /* Retry if chip was in standby */
 140         if (ret == -EREMOTEIO) {
 141                 nfc_info(drv_data->dev, "chip may sleep, retry\n");
 142                 usleep_range(6000, 10000);
 143                 ret = i2c_master_send(drv_data->i2c, skb->data, skb->len);
 144         }
 145 
 146         if (ret >= 0) {
 147                 if (ret != skb->len) {
 148                         nfc_err(drv_data->dev,
 149                                 "Invalid length sent: %u (expected %u)\n",
 150                                 ret, skb->len);
 151                         ret = -EREMOTEIO;
 152                 } else
 153                         ret = 0;
 154                 kfree_skb(skb);
 155         }
 156 
 157         return ret;
 158 }
 159 
 160 static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
 161                                           const void *param)
 162 {
 163 }
 164 
 165 static struct nfcmrvl_if_ops i2c_ops = {
 166         .nci_open = nfcmrvl_i2c_nci_open,
 167         .nci_close = nfcmrvl_i2c_nci_close,
 168         .nci_send = nfcmrvl_i2c_nci_send,
 169         .nci_update_config = nfcmrvl_i2c_nci_update_config,
 170 };
 171 
 172 static int nfcmrvl_i2c_parse_dt(struct device_node *node,
 173                                 struct nfcmrvl_platform_data *pdata)
 174 {
 175         int ret;
 176 
 177         ret = nfcmrvl_parse_dt(node, pdata);
 178         if (ret < 0) {
 179                 pr_err("Failed to get generic entries\n");
 180                 return ret;
 181         }
 182 
 183         if (of_find_property(node, "i2c-int-falling", NULL))
 184                 pdata->irq_polarity = IRQF_TRIGGER_FALLING;
 185         else
 186                 pdata->irq_polarity = IRQF_TRIGGER_RISING;
 187 
 188         ret = irq_of_parse_and_map(node, 0);
 189         if (ret < 0) {
 190                 pr_err("Unable to get irq, error: %d\n", ret);
 191                 return ret;
 192         }
 193         pdata->irq = ret;
 194 
 195         return 0;
 196 }
 197 
 198 static int nfcmrvl_i2c_probe(struct i2c_client *client,
 199                              const struct i2c_device_id *id)
 200 {
 201         struct nfcmrvl_i2c_drv_data *drv_data;
 202         struct nfcmrvl_platform_data *pdata;
 203         struct nfcmrvl_platform_data config;
 204         int ret;
 205 
 206         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 207                 nfc_err(&client->dev, "Need I2C_FUNC_I2C\n");
 208                 return -ENODEV;
 209         }
 210 
 211         drv_data = devm_kzalloc(&client->dev, sizeof(*drv_data), GFP_KERNEL);
 212         if (!drv_data)
 213                 return -ENOMEM;
 214 
 215         drv_data->i2c = client;
 216         drv_data->dev = &client->dev;
 217         drv_data->priv = NULL;
 218 
 219         i2c_set_clientdata(client, drv_data);
 220 
 221         pdata = client->dev.platform_data;
 222 
 223         if (!pdata && client->dev.of_node)
 224                 if (nfcmrvl_i2c_parse_dt(client->dev.of_node, &config) == 0)
 225                         pdata = &config;
 226 
 227         if (!pdata)
 228                 return -EINVAL;
 229 
 230         /* Request the read IRQ */
 231         ret = devm_request_threaded_irq(&drv_data->i2c->dev, pdata->irq,
 232                                         NULL, nfcmrvl_i2c_int_irq_thread_fn,
 233                                         pdata->irq_polarity | IRQF_ONESHOT,
 234                                         "nfcmrvl_i2c_int", drv_data);
 235         if (ret < 0) {
 236                 nfc_err(&drv_data->i2c->dev,
 237                         "Unable to register IRQ handler\n");
 238                 return ret;
 239         }
 240 
 241         drv_data->priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_I2C,
 242                                                   drv_data, &i2c_ops,
 243                                                   &drv_data->i2c->dev, pdata);
 244 
 245         if (IS_ERR(drv_data->priv))
 246                 return PTR_ERR(drv_data->priv);
 247 
 248         drv_data->priv->support_fw_dnld = true;
 249 
 250         return 0;
 251 }
 252 
 253 static int nfcmrvl_i2c_remove(struct i2c_client *client)
 254 {
 255         struct nfcmrvl_i2c_drv_data *drv_data = i2c_get_clientdata(client);
 256 
 257         nfcmrvl_nci_unregister_dev(drv_data->priv);
 258 
 259         return 0;
 260 }
 261 
 262 
 263 static const struct of_device_id of_nfcmrvl_i2c_match[] = {
 264         { .compatible = "marvell,nfc-i2c", },
 265         {},
 266 };
 267 MODULE_DEVICE_TABLE(of, of_nfcmrvl_i2c_match);
 268 
 269 static const struct i2c_device_id nfcmrvl_i2c_id_table[] = {
 270         { "nfcmrvl_i2c", 0 },
 271         {}
 272 };
 273 MODULE_DEVICE_TABLE(i2c, nfcmrvl_i2c_id_table);
 274 
 275 static struct i2c_driver nfcmrvl_i2c_driver = {
 276         .probe = nfcmrvl_i2c_probe,
 277         .id_table = nfcmrvl_i2c_id_table,
 278         .remove = nfcmrvl_i2c_remove,
 279         .driver = {
 280                 .name           = "nfcmrvl_i2c",
 281                 .owner          = THIS_MODULE,
 282                 .of_match_table = of_match_ptr(of_nfcmrvl_i2c_match),
 283         },
 284 };
 285 
 286 module_i2c_driver(nfcmrvl_i2c_driver);
 287 
 288 MODULE_AUTHOR("Marvell International Ltd.");
 289 MODULE_DESCRIPTION("Marvell NFC-over-I2C driver");
 290 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */