2019-05-19 15:51:43 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2016-03-25 15:46:54 +01:00
/*
* Driver for NXP PN533 NFC Chip - I2C transport layer
*
* Copyright ( C ) 2011 Instituto Nokia de Tecnologia
* Copyright ( C ) 2012 - 2013 Tieto Poland
* Copyright ( C ) 2016 HALE electronic
*/
# include <linux/device.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/slab.h>
# include <linux/i2c.h>
# include <linux/nfc.h>
# include <linux/netdevice.h>
# include <linux/interrupt.h>
# include <net/nfc/nfc.h>
# include "pn533.h"
# define VERSION "0.1"
# define PN533_I2C_DRIVER_NAME "pn533_i2c"
struct pn533_i2c_phy {
struct i2c_client * i2c_dev ;
struct pn533 * priv ;
2016-04-21 16:43:51 +02:00
bool aborted ;
2016-03-25 15:46:54 +01:00
int hard_fault ; /*
* < 0 if hardware error occurred ( e . g . i2c err )
* and prevents normal operation .
*/
} ;
static int pn533_i2c_send_ack ( struct pn533 * dev , gfp_t flags )
{
struct pn533_i2c_phy * phy = dev - > phy ;
struct i2c_client * client = phy - > i2c_dev ;
2017-04-06 05:49:02 +02:00
static const u8 ack [ 6 ] = { 0x00 , 0x00 , 0xff , 0x00 , 0xff , 0x00 } ;
2016-03-25 15:46:54 +01:00
/* spec 6.2.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */
int rc ;
rc = i2c_master_send ( client , ack , 6 ) ;
return rc ;
}
static int pn533_i2c_send_frame ( struct pn533 * dev ,
struct sk_buff * out )
{
struct pn533_i2c_phy * phy = dev - > phy ;
struct i2c_client * client = phy - > i2c_dev ;
int rc ;
if ( phy - > hard_fault ! = 0 )
return phy - > hard_fault ;
if ( phy - > priv = = NULL )
phy - > priv = dev ;
2016-04-21 16:43:51 +02:00
phy - > aborted = false ;
2016-03-25 15:46:54 +01:00
print_hex_dump_debug ( " PN533_i2c TX: " , DUMP_PREFIX_NONE , 16 , 1 ,
out - > data , out - > len , false ) ;
rc = i2c_master_send ( client , out - > data , out - > len ) ;
if ( rc = = - EREMOTEIO ) { /* Retry, chip was in power down */
usleep_range ( 6000 , 10000 ) ;
rc = i2c_master_send ( client , out - > data , out - > len ) ;
}
if ( rc > = 0 ) {
if ( rc ! = out - > len )
rc = - EREMOTEIO ;
else
rc = 0 ;
}
return rc ;
}
static void pn533_i2c_abort_cmd ( struct pn533 * dev , gfp_t flags )
{
2016-04-21 16:43:51 +02:00
struct pn533_i2c_phy * phy = dev - > phy ;
phy - > aborted = true ;
2016-03-25 15:46:54 +01:00
/* An ack will cancel the last issued command */
pn533_i2c_send_ack ( dev , flags ) ;
/* schedule cmd_complete_work to finish current command execution */
2016-04-21 16:43:51 +02:00
pn533_recv_frame ( phy - > priv , NULL , - ENOENT ) ;
2016-03-25 15:46:54 +01:00
}
static int pn533_i2c_read ( struct pn533_i2c_phy * phy , struct sk_buff * * skb )
{
struct i2c_client * client = phy - > i2c_dev ;
int len = PN533_EXT_FRAME_HEADER_LEN +
PN533_STD_FRAME_MAX_PAYLOAD_LEN +
PN533_STD_FRAME_TAIL_LEN + 1 ;
int r ;
* skb = alloc_skb ( len , GFP_KERNEL ) ;
if ( * skb = = NULL )
return - ENOMEM ;
r = i2c_master_recv ( client , skb_put ( * skb , len ) , len ) ;
if ( r ! = len ) {
nfc_err ( & client - > dev , " cannot read. r=%d len=%d \n " , r , len ) ;
kfree_skb ( * skb ) ;
return - EREMOTEIO ;
}
if ( ! ( ( * skb ) - > data [ 0 ] & 0x01 ) ) {
nfc_err ( & client - > dev , " READY flag not set " ) ;
kfree_skb ( * skb ) ;
return - EBUSY ;
}
/* remove READY byte */
skb_pull ( * skb , 1 ) ;
/* trim to frame size */
skb_trim ( * skb , phy - > priv - > ops - > rx_frame_size ( ( * skb ) - > data ) ) ;
return 0 ;
}
static irqreturn_t pn533_i2c_irq_thread_fn ( int irq , void * data )
{
struct pn533_i2c_phy * phy = data ;
struct i2c_client * client ;
struct sk_buff * skb = NULL ;
int r ;
if ( ! phy | | irq ! = phy - > i2c_dev - > irq ) {
WARN_ON_ONCE ( 1 ) ;
return IRQ_NONE ;
}
client = phy - > i2c_dev ;
dev_dbg ( & client - > dev , " IRQ \n " ) ;
if ( phy - > hard_fault ! = 0 )
return IRQ_HANDLED ;
r = pn533_i2c_read ( phy , & skb ) ;
if ( r = = - EREMOTEIO ) {
phy - > hard_fault = r ;
pn533_recv_frame ( phy - > priv , NULL , - EREMOTEIO ) ;
return IRQ_HANDLED ;
} else if ( ( r = = - ENOMEM ) | | ( r = = - EBADMSG ) | | ( r = = - EBUSY ) ) {
return IRQ_HANDLED ;
}
2016-04-21 16:43:51 +02:00
if ( ! phy - > aborted )
pn533_recv_frame ( phy - > priv , skb , 0 ) ;
2016-03-25 15:46:54 +01:00
return IRQ_HANDLED ;
}
static struct pn533_phy_ops i2c_phy_ops = {
. send_frame = pn533_i2c_send_frame ,
. send_ack = pn533_i2c_send_ack ,
. abort_cmd = pn533_i2c_abort_cmd ,
} ;
static int pn533_i2c_probe ( struct i2c_client * client ,
const struct i2c_device_id * id )
{
struct pn533_i2c_phy * phy ;
struct pn533 * priv ;
int r = 0 ;
dev_dbg ( & client - > dev , " %s \n " , __func__ ) ;
dev_dbg ( & client - > dev , " IRQ: %d \n " , client - > irq ) ;
if ( ! i2c_check_functionality ( client - > adapter , I2C_FUNC_I2C ) ) {
nfc_err ( & client - > dev , " Need I2C_FUNC_I2C \n " ) ;
return - ENODEV ;
}
phy = devm_kzalloc ( & client - > dev , sizeof ( struct pn533_i2c_phy ) ,
GFP_KERNEL ) ;
if ( ! phy )
return - ENOMEM ;
phy - > i2c_dev = client ;
i2c_set_clientdata ( client , phy ) ;
2019-10-29 15:46:46 +01:00
priv = pn53x_common_init ( PN533_DEVICE_PN532 ,
PN533_PROTO_REQ_ACK_RESP ,
phy , & i2c_phy_ops , NULL ,
& phy - > i2c_dev - > dev ) ;
2016-03-25 15:46:54 +01:00
if ( IS_ERR ( priv ) ) {
r = PTR_ERR ( priv ) ;
2016-12-28 20:10:59 +03:00
return r ;
2016-03-25 15:46:54 +01:00
}
phy - > priv = priv ;
2019-10-29 15:46:46 +01:00
r = pn532_i2c_nfc_alloc ( priv , PN533_NO_TYPE_B_PROTOCOLS , & client - > dev ) ;
if ( r )
goto nfc_alloc_err ;
2016-03-25 15:46:54 +01:00
2016-12-28 20:10:59 +03:00
r = request_threaded_irq ( client - > irq , NULL , pn533_i2c_irq_thread_fn ,
IRQF_TRIGGER_FALLING |
IRQF_SHARED | IRQF_ONESHOT ,
PN533_I2C_DRIVER_NAME , phy ) ;
if ( r < 0 ) {
nfc_err ( & client - > dev , " Unable to register IRQ handler \n " ) ;
goto irq_rqst_err ;
}
r = pn533_finalize_setup ( priv ) ;
if ( r )
goto fn_setup_err ;
2019-10-29 15:46:46 +01:00
r = nfc_register_device ( priv - > nfc_dev ) ;
if ( r )
goto fn_setup_err ;
return r ;
2016-03-25 15:46:54 +01:00
2016-12-28 20:10:59 +03:00
fn_setup_err :
2016-03-25 15:46:54 +01:00
free_irq ( client - > irq , phy ) ;
2016-12-28 20:10:59 +03:00
irq_rqst_err :
2019-10-29 15:46:46 +01:00
nfc_free_device ( priv - > nfc_dev ) ;
nfc_alloc_err :
pn53x_common_clean ( phy - > priv ) ;
2016-12-28 20:10:59 +03:00
2016-03-25 15:46:54 +01:00
return r ;
}
static int pn533_i2c_remove ( struct i2c_client * client )
{
struct pn533_i2c_phy * phy = i2c_get_clientdata ( client ) ;
dev_dbg ( & client - > dev , " %s \n " , __func__ ) ;
2016-04-21 16:43:49 +02:00
free_irq ( client - > irq , phy ) ;
2019-10-29 15:46:46 +01:00
pn53x_unregister_nfc ( phy - > priv ) ;
pn53x_common_clean ( phy - > priv ) ;
2016-12-28 20:10:57 +03:00
2016-03-25 15:46:54 +01:00
return 0 ;
}
static const struct of_device_id of_pn533_i2c_match [ ] = {
2019-10-29 15:43:14 +01:00
{ . compatible = " nxp,pn532 " , } ,
/*
* NOTE : The use of the compatibles with the trailing " ...-i2c " is
* deprecated and will be removed .
*/
2016-03-25 15:46:54 +01:00
{ . compatible = " nxp,pn533-i2c " , } ,
{ . compatible = " nxp,pn532-i2c " , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , of_pn533_i2c_match ) ;
2017-08-21 22:33:56 +05:30
static const struct i2c_device_id pn533_i2c_id_table [ ] = {
2016-03-25 15:46:54 +01:00
{ PN533_I2C_DRIVER_NAME , 0 } ,
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , pn533_i2c_id_table ) ;
static struct i2c_driver pn533_i2c_driver = {
. driver = {
. name = PN533_I2C_DRIVER_NAME ,
. of_match_table = of_match_ptr ( of_pn533_i2c_match ) ,
} ,
. probe = pn533_i2c_probe ,
. id_table = pn533_i2c_id_table ,
. remove = pn533_i2c_remove ,
} ;
module_i2c_driver ( pn533_i2c_driver ) ;
MODULE_AUTHOR ( " Michael Thalmeier <michael.thalmeier@hale.at> " ) ;
MODULE_DESCRIPTION ( " PN533 I2C driver ver " VERSION ) ;
MODULE_VERSION ( VERSION ) ;
MODULE_LICENSE ( " GPL " ) ;