2019-05-30 02:57:47 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2007-10-20 15:42:36 +04:00
/*
* Texas Instruments ' Bluetooth HCILL UART protocol
*
* HCILL ( HCI Low Level ) is a Texas Instruments ' power management
* protocol extension to H4 .
*
* Copyright ( C ) 2007 Texas Instruments , Inc .
*
* Written by Ohad Ben - Cohen < ohad @ bencohen . org >
*
* Acknowledgements :
* This file is based on hci_h4 . c , which was written
* by Maxim Krasnyansky and Marcel Holtmann .
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/sched.h>
# include <linux/types.h>
# include <linux/fcntl.h>
2017-04-13 18:03:52 +03:00
# include <linux/firmware.h>
2007-10-20 15:42:36 +04:00
# include <linux/interrupt.h>
# include <linux/ptrace.h>
# include <linux/poll.h>
# include <linux/slab.h>
# include <linux/errno.h>
# include <linux/string.h>
# include <linux/signal.h>
# include <linux/ioctl.h>
2017-04-13 18:03:52 +03:00
# include <linux/of.h>
# include <linux/serdev.h>
2007-10-20 15:42:36 +04:00
# include <linux/skbuff.h>
2017-04-13 18:03:52 +03:00
# include <linux/ti_wilink_st.h>
2017-06-07 12:08:21 +03:00
# include <linux/clk.h>
2007-10-20 15:42:36 +04:00
# include <net/bluetooth/bluetooth.h>
# include <net/bluetooth/hci_core.h>
2017-04-13 18:03:52 +03:00
# include <linux/gpio/consumer.h>
2017-12-13 02:54:12 +03:00
# include <linux/nvmem-consumer.h>
2007-10-20 15:42:36 +04:00
# include "hci_uart.h"
2017-12-04 06:21:21 +03:00
/* Vendor-specific HCI commands */
2017-12-13 00:59:16 +03:00
# define HCI_VS_WRITE_BD_ADDR 0xfc06
2017-12-04 06:21:21 +03:00
# define HCI_VS_UPDATE_UART_HCI_BAUDRATE 0xff36
2007-10-20 15:42:36 +04:00
/* HCILL commands */
# define HCILL_GO_TO_SLEEP_IND 0x30
# define HCILL_GO_TO_SLEEP_ACK 0x31
# define HCILL_WAKE_UP_IND 0x32
# define HCILL_WAKE_UP_ACK 0x33
/* HCILL states */
enum hcill_states_e {
HCILL_ASLEEP ,
HCILL_ASLEEP_TO_AWAKE ,
HCILL_AWAKE ,
HCILL_AWAKE_TO_ASLEEP
} ;
2017-04-13 18:03:52 +03:00
struct ll_device {
struct hci_uart hu ;
struct serdev_device * serdev ;
struct gpio_desc * enable_gpio ;
2017-06-07 12:08:21 +03:00
struct clk * ext_clk ;
2017-12-13 02:54:12 +03:00
bdaddr_t bdaddr ;
2017-04-13 18:03:52 +03:00
} ;
2007-10-20 15:42:36 +04:00
struct ll_struct {
struct sk_buff * rx_skb ;
struct sk_buff_head txq ;
spinlock_t hcill_lock ; /* HCILL state lock */
unsigned long hcill_state ; /* HCILL power state */
struct sk_buff_head tx_wait_q ; /* HCILL wait queue */
} ;
/*
* Builds and sends an HCILL command packet .
* These are very simple packets with only 1 cmd byte
*/
static int send_hcill_cmd ( u8 cmd , struct hci_uart * hu )
{
int err = 0 ;
struct sk_buff * skb = NULL ;
struct ll_struct * ll = hu - > priv ;
BT_DBG ( " hu %p cmd 0x%x " , hu , cmd ) ;
/* allocate packet */
skb = bt_skb_alloc ( 1 , GFP_ATOMIC ) ;
if ( ! skb ) {
BT_ERR ( " cannot allocate memory for HCILL packet " ) ;
err = - ENOMEM ;
goto out ;
}
/* prepare packet */
2018-03-20 11:31:04 +03:00
skb_put_u8 ( skb , cmd ) ;
2007-10-20 15:42:36 +04:00
/* send packet */
skb_queue_tail ( & ll - > txq , skb ) ;
out :
return err ;
}
/* Initialize protocol */
static int ll_open ( struct hci_uart * hu )
{
struct ll_struct * ll ;
BT_DBG ( " hu %p " , hu ) ;
2012-01-07 18:19:37 +04:00
ll = kzalloc ( sizeof ( * ll ) , GFP_KERNEL ) ;
2007-10-20 15:42:36 +04:00
if ( ! ll )
return - ENOMEM ;
skb_queue_head_init ( & ll - > txq ) ;
skb_queue_head_init ( & ll - > tx_wait_q ) ;
spin_lock_init ( & ll - > hcill_lock ) ;
ll - > hcill_state = HCILL_AWAKE ;
hu - > priv = ll ;
2017-06-07 12:08:21 +03:00
if ( hu - > serdev ) {
struct ll_device * lldev = serdev_device_get_drvdata ( hu - > serdev ) ;
2019-06-24 00:15:48 +03:00
2017-06-07 12:08:21 +03:00
if ( ! IS_ERR ( lldev - > ext_clk ) )
clk_prepare_enable ( lldev - > ext_clk ) ;
}
2017-04-13 18:03:52 +03:00
2007-10-20 15:42:36 +04:00
return 0 ;
}
/* Flush protocol data */
static int ll_flush ( struct hci_uart * hu )
{
struct ll_struct * ll = hu - > priv ;
BT_DBG ( " hu %p " , hu ) ;
skb_queue_purge ( & ll - > tx_wait_q ) ;
skb_queue_purge ( & ll - > txq ) ;
return 0 ;
}
/* Close protocol */
static int ll_close ( struct hci_uart * hu )
{
struct ll_struct * ll = hu - > priv ;
BT_DBG ( " hu %p " , hu ) ;
skb_queue_purge ( & ll - > tx_wait_q ) ;
skb_queue_purge ( & ll - > txq ) ;
2009-02-25 13:09:33 +03:00
kfree_skb ( ll - > rx_skb ) ;
2007-10-20 15:42:36 +04:00
2017-04-13 18:03:52 +03:00
if ( hu - > serdev ) {
struct ll_device * lldev = serdev_device_get_drvdata ( hu - > serdev ) ;
2019-06-24 00:15:48 +03:00
2017-04-13 18:03:52 +03:00
gpiod_set_value_cansleep ( lldev - > enable_gpio , 0 ) ;
2017-06-07 12:08:21 +03:00
clk_disable_unprepare ( lldev - > ext_clk ) ;
2017-04-13 18:03:52 +03:00
}
2007-10-20 15:42:36 +04:00
hu - > priv = NULL ;
kfree ( ll ) ;
return 0 ;
}
/*
* internal function , which does common work of the device wake up process :
* 1. places all pending packets ( waiting in tx_wait_q list ) in txq list .
* 2. changes internal state to HCILL_AWAKE .
* Note : assumes that hcill_lock spinlock is taken ,
* shouldn ' t be called otherwise !
*/
static void __ll_do_awake ( struct ll_struct * ll )
{
struct sk_buff * skb = NULL ;
while ( ( skb = skb_dequeue ( & ll - > tx_wait_q ) ) )
skb_queue_tail ( & ll - > txq , skb ) ;
ll - > hcill_state = HCILL_AWAKE ;
}
/*
* Called upon a wake - up - indication from the device
*/
static void ll_device_want_to_wakeup ( struct hci_uart * hu )
{
unsigned long flags ;
struct ll_struct * ll = hu - > priv ;
BT_DBG ( " hu %p " , hu ) ;
/* lock hcill state */
spin_lock_irqsave ( & ll - > hcill_lock , flags ) ;
switch ( ll - > hcill_state ) {
2008-01-11 09:24:43 +03:00
case HCILL_ASLEEP_TO_AWAKE :
/*
* This state means that both the host and the BRF chip
* have simultaneously sent a wake - up - indication packet .
2011-03-31 05:57:33 +04:00
* Traditionally , in this case , receiving a wake - up - indication
2008-01-11 09:24:43 +03:00
* was enough and an additional wake - up - ack wasn ' t needed .
* This has changed with the BRF6350 , which does require an
* explicit wake - up - ack . Other BRF versions , which do not
* require an explicit ack here , do accept it , thus it is
* perfectly safe to always send one .
*/
BT_DBG ( " dual wake-up-indication " ) ;
2020-07-08 23:26:50 +03:00
fallthrough ;
2007-10-20 15:42:36 +04:00
case HCILL_ASLEEP :
/* acknowledge device wake up */
if ( send_hcill_cmd ( HCILL_WAKE_UP_ACK , hu ) < 0 ) {
BT_ERR ( " cannot acknowledge device wake up " ) ;
goto out ;
}
break ;
default :
2008-01-11 09:24:43 +03:00
/* any other state is illegal */
2019-06-24 00:15:48 +03:00
BT_ERR ( " received HCILL_WAKE_UP_IND in state %ld " ,
ll - > hcill_state ) ;
2007-10-20 15:42:36 +04:00
break ;
}
/* send pending packets and change state to HCILL_AWAKE */
__ll_do_awake ( ll ) ;
out :
spin_unlock_irqrestore ( & ll - > hcill_lock , flags ) ;
/* actually send the packets */
hci_uart_tx_wakeup ( hu ) ;
}
/*
* Called upon a sleep - indication from the device
*/
static void ll_device_want_to_sleep ( struct hci_uart * hu )
{
unsigned long flags ;
struct ll_struct * ll = hu - > priv ;
BT_DBG ( " hu %p " , hu ) ;
/* lock hcill state */
spin_lock_irqsave ( & ll - > hcill_lock , flags ) ;
/* sanity check */
if ( ll - > hcill_state ! = HCILL_AWAKE )
2019-06-24 00:15:48 +03:00
BT_ERR ( " ERR: HCILL_GO_TO_SLEEP_IND in state %ld " ,
ll - > hcill_state ) ;
2007-10-20 15:42:36 +04:00
/* acknowledge device sleep */
if ( send_hcill_cmd ( HCILL_GO_TO_SLEEP_ACK , hu ) < 0 ) {
BT_ERR ( " cannot acknowledge device sleep " ) ;
goto out ;
}
/* update state */
ll - > hcill_state = HCILL_ASLEEP ;
out :
spin_unlock_irqrestore ( & ll - > hcill_lock , flags ) ;
/* actually send the sleep ack packet */
hci_uart_tx_wakeup ( hu ) ;
}
/*
* Called upon wake - up - acknowledgement from the device
*/
static void ll_device_woke_up ( struct hci_uart * hu )
{
unsigned long flags ;
struct ll_struct * ll = hu - > priv ;
BT_DBG ( " hu %p " , hu ) ;
/* lock hcill state */
spin_lock_irqsave ( & ll - > hcill_lock , flags ) ;
/* sanity check */
if ( ll - > hcill_state ! = HCILL_ASLEEP_TO_AWAKE )
2019-06-24 00:15:48 +03:00
BT_ERR ( " received HCILL_WAKE_UP_ACK in state %ld " ,
ll - > hcill_state ) ;
2007-10-20 15:42:36 +04:00
/* send pending packets and change state to HCILL_AWAKE */
__ll_do_awake ( ll ) ;
spin_unlock_irqrestore ( & ll - > hcill_lock , flags ) ;
/* actually send the packets */
hci_uart_tx_wakeup ( hu ) ;
}
/* Enqueue frame for transmittion (padding, crc, etc) */
/* may be called from two simultaneous tasklets */
static int ll_enqueue ( struct hci_uart * hu , struct sk_buff * skb )
{
unsigned long flags = 0 ;
struct ll_struct * ll = hu - > priv ;
BT_DBG ( " hu %p skb %p " , hu , skb ) ;
/* Prepend skb with frame type */
2015-11-05 09:33:56 +03:00
memcpy ( skb_push ( skb , 1 ) , & hci_skb_pkt_type ( skb ) , 1 ) ;
2007-10-20 15:42:36 +04:00
/* lock hcill state */
spin_lock_irqsave ( & ll - > hcill_lock , flags ) ;
/* act according to current state */
switch ( ll - > hcill_state ) {
case HCILL_AWAKE :
BT_DBG ( " device awake, sending normally " ) ;
skb_queue_tail ( & ll - > txq , skb ) ;
break ;
case HCILL_ASLEEP :
BT_DBG ( " device asleep, waking up and queueing packet " ) ;
/* save packet for later */
skb_queue_tail ( & ll - > tx_wait_q , skb ) ;
/* awake device */
if ( send_hcill_cmd ( HCILL_WAKE_UP_IND , hu ) < 0 ) {
BT_ERR ( " cannot wake up device " ) ;
break ;
}
ll - > hcill_state = HCILL_ASLEEP_TO_AWAKE ;
break ;
case HCILL_ASLEEP_TO_AWAKE :
BT_DBG ( " device waking up, queueing packet " ) ;
/* transient state; just keep packet for later */
skb_queue_tail ( & ll - > tx_wait_q , skb ) ;
break ;
default :
2019-06-24 00:15:48 +03:00
BT_ERR ( " illegal hcill state: %ld (losing packet) " ,
ll - > hcill_state ) ;
2022-12-07 05:18:31 +03:00
dev_kfree_skb_irq ( skb ) ;
2007-10-20 15:42:36 +04:00
break ;
}
spin_unlock_irqrestore ( & ll - > hcill_lock , flags ) ;
return 0 ;
}
2018-03-24 12:19:52 +03:00
static int ll_recv_frame ( struct hci_dev * hdev , struct sk_buff * skb )
2007-10-20 15:42:36 +04:00
{
2018-03-24 12:19:52 +03:00
struct hci_uart * hu = hci_get_drvdata ( hdev ) ;
struct ll_struct * ll = hu - > priv ;
2007-10-20 15:42:36 +04:00
2018-03-24 12:19:52 +03:00
switch ( hci_skb_pkt_type ( skb ) ) {
case HCILL_GO_TO_SLEEP_IND :
BT_DBG ( " HCILL_GO_TO_SLEEP_IND packet " ) ;
ll_device_want_to_sleep ( hu ) ;
break ;
case HCILL_GO_TO_SLEEP_ACK :
/* shouldn't happen */
bt_dev_err ( hdev , " received HCILL_GO_TO_SLEEP_ACK in state %ld " ,
ll - > hcill_state ) ;
break ;
case HCILL_WAKE_UP_IND :
BT_DBG ( " HCILL_WAKE_UP_IND packet " ) ;
ll_device_want_to_wakeup ( hu ) ;
break ;
case HCILL_WAKE_UP_ACK :
BT_DBG ( " HCILL_WAKE_UP_ACK packet " ) ;
ll_device_woke_up ( hu ) ;
break ;
}
2007-10-20 15:42:36 +04:00
2018-03-24 12:19:52 +03:00
kfree_skb ( skb ) ;
2007-10-20 15:42:36 +04:00
return 0 ;
}
2018-03-24 12:19:52 +03:00
# define LL_RECV_SLEEP_IND \
. type = HCILL_GO_TO_SLEEP_IND , \
. hlen = 0 , \
. loff = 0 , \
. lsize = 0 , \
. maxlen = 0
# define LL_RECV_SLEEP_ACK \
. type = HCILL_GO_TO_SLEEP_ACK , \
. hlen = 0 , \
. loff = 0 , \
. lsize = 0 , \
. maxlen = 0
# define LL_RECV_WAKE_IND \
. type = HCILL_WAKE_UP_IND , \
. hlen = 0 , \
. loff = 0 , \
. lsize = 0 , \
. maxlen = 0
# define LL_RECV_WAKE_ACK \
. type = HCILL_WAKE_UP_ACK , \
. hlen = 0 , \
. loff = 0 , \
. lsize = 0 , \
. maxlen = 0
static const struct h4_recv_pkt ll_recv_pkts [ ] = {
{ H4_RECV_ACL , . recv = hci_recv_frame } ,
{ H4_RECV_SCO , . recv = hci_recv_frame } ,
{ H4_RECV_EVENT , . recv = hci_recv_frame } ,
{ LL_RECV_SLEEP_IND , . recv = ll_recv_frame } ,
{ LL_RECV_SLEEP_ACK , . recv = ll_recv_frame } ,
{ LL_RECV_WAKE_IND , . recv = ll_recv_frame } ,
{ LL_RECV_WAKE_ACK , . recv = ll_recv_frame } ,
} ;
2007-10-20 15:42:36 +04:00
/* Recv data */
2015-04-05 06:59:41 +03:00
static int ll_recv ( struct hci_uart * hu , const void * data , int count )
2007-10-20 15:42:36 +04:00
{
struct ll_struct * ll = hu - > priv ;
2018-03-24 12:19:52 +03:00
if ( ! test_bit ( HCI_UART_REGISTERED , & hu - > flags ) )
return - EUNATCH ;
2007-10-20 15:42:36 +04:00
2018-03-24 12:19:52 +03:00
ll - > rx_skb = h4_recv_buf ( hu - > hdev , ll - > rx_skb , data , count ,
ll_recv_pkts , ARRAY_SIZE ( ll_recv_pkts ) ) ;
if ( IS_ERR ( ll - > rx_skb ) ) {
int err = PTR_ERR ( ll - > rx_skb ) ;
bt_dev_err ( hu - > hdev , " Frame reassembly failed (%d) " , err ) ;
ll - > rx_skb = NULL ;
return err ;
2007-10-20 15:42:36 +04:00
}
return count ;
}
static struct sk_buff * ll_dequeue ( struct hci_uart * hu )
{
struct ll_struct * ll = hu - > priv ;
2019-06-24 00:15:48 +03:00
2007-10-20 15:42:36 +04:00
return skb_dequeue ( & ll - > txq ) ;
}
2017-04-13 18:03:52 +03:00
# if IS_ENABLED(CONFIG_SERIAL_DEV_BUS)
static int read_local_version ( struct hci_dev * hdev )
{
int err = 0 ;
unsigned short version = 0 ;
struct sk_buff * skb ;
struct hci_rp_read_local_version * ver ;
2019-06-24 00:15:48 +03:00
skb = __hci_cmd_sync ( hdev , HCI_OP_READ_LOCAL_VERSION , 0 , NULL ,
HCI_INIT_TIMEOUT ) ;
2017-04-13 18:03:52 +03:00
if ( IS_ERR ( skb ) ) {
bt_dev_err ( hdev , " Reading TI version information failed (%ld) " ,
PTR_ERR ( skb ) ) ;
2017-04-16 00:54:13 +03:00
return PTR_ERR ( skb ) ;
2017-04-13 18:03:52 +03:00
}
if ( skb - > len ! = sizeof ( * ver ) ) {
err = - EILSEQ ;
goto out ;
}
ver = ( struct hci_rp_read_local_version * ) skb - > data ;
if ( le16_to_cpu ( ver - > manufacturer ) ! = 13 ) {
err = - ENODEV ;
goto out ;
}
version = le16_to_cpu ( ver - > lmp_subver ) ;
out :
2019-06-24 00:15:48 +03:00
if ( err )
bt_dev_err ( hdev , " Failed to read TI version info: %d " , err ) ;
2017-04-13 18:03:52 +03:00
kfree_skb ( skb ) ;
return err ? err : version ;
}
2019-07-01 23:57:13 +03:00
static int send_command_from_firmware ( struct ll_device * lldev ,
struct hci_command * cmd )
{
struct sk_buff * skb ;
if ( cmd - > opcode = = HCI_VS_UPDATE_UART_HCI_BAUDRATE ) {
/* ignore remote change
* baud rate HCI VS command
*/
bt_dev_warn ( lldev - > hu . hdev ,
" change remote baud rate command in firmware " ) ;
return 0 ;
}
if ( cmd - > prefix ! = 1 )
bt_dev_dbg ( lldev - > hu . hdev , " command type %d " , cmd - > prefix ) ;
skb = __hci_cmd_sync ( lldev - > hu . hdev , cmd - > opcode , cmd - > plen ,
& cmd - > speed , HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
bt_dev_err ( lldev - > hu . hdev , " send command failed " ) ;
return PTR_ERR ( skb ) ;
}
kfree_skb ( skb ) ;
return 0 ;
}
2022-01-15 04:03:29 +03:00
/*
2017-04-13 18:03:52 +03:00
* download_firmware -
* internal function which parses through the . bts firmware
* script file intreprets SEND , DELAY actions only as of now
*/
static int download_firmware ( struct ll_device * lldev )
{
unsigned short chip , min_ver , maj_ver ;
int version , err , len ;
unsigned char * ptr , * action_ptr ;
unsigned char bts_scr_name [ 40 ] ; /* 40 char long bts scr name? */
const struct firmware * fw ;
struct hci_command * cmd ;
version = read_local_version ( lldev - > hu . hdev ) ;
if ( version < 0 )
return version ;
chip = ( version & 0x7C00 ) > > 10 ;
min_ver = ( version & 0x007F ) ;
maj_ver = ( version & 0x0380 ) > > 7 ;
if ( version & 0x8000 )
maj_ver | = 0x0008 ;
snprintf ( bts_scr_name , sizeof ( bts_scr_name ) ,
" ti-connectivity/TIInit_%d.%d.%d.bts " ,
chip , maj_ver , min_ver ) ;
err = request_firmware ( & fw , bts_scr_name , & lldev - > serdev - > dev ) ;
if ( err | | ! fw - > data | | ! fw - > size ) {
bt_dev_err ( lldev - > hu . hdev , " request_firmware failed(errno %d) for %s " ,
err , bts_scr_name ) ;
return - EINVAL ;
}
ptr = ( void * ) fw - > data ;
len = fw - > size ;
/* bts_header to remove out magic number and
* version
*/
ptr + = sizeof ( struct bts_header ) ;
len - = sizeof ( struct bts_header ) ;
while ( len > 0 & & ptr ) {
bt_dev_dbg ( lldev - > hu . hdev , " action size %d, type %d " ,
( ( struct bts_action * ) ptr ) - > size ,
( ( struct bts_action * ) ptr ) - > type ) ;
action_ptr = & ( ( ( struct bts_action * ) ptr ) - > data [ 0 ] ) ;
switch ( ( ( struct bts_action * ) ptr ) - > type ) {
case ACTION_SEND_COMMAND : /* action send */
bt_dev_dbg ( lldev - > hu . hdev , " S " ) ;
cmd = ( struct hci_command * ) action_ptr ;
2019-07-01 23:57:13 +03:00
err = send_command_from_firmware ( lldev , cmd ) ;
if ( err )
2017-04-13 18:03:52 +03:00
goto out_rel_fw ;
break ;
case ACTION_WAIT_EVENT : /* wait */
/* no need to wait as command was synchronous */
bt_dev_dbg ( lldev - > hu . hdev , " W " ) ;
break ;
case ACTION_DELAY : /* sleep */
bt_dev_info ( lldev - > hu . hdev , " sleep command in scr " ) ;
2018-01-27 13:03:52 +03:00
msleep ( ( ( struct bts_action_delay * ) action_ptr ) - > msec ) ;
2017-04-13 18:03:52 +03:00
break ;
}
len - = ( sizeof ( struct bts_action ) +
( ( struct bts_action * ) ptr ) - > size ) ;
ptr + = sizeof ( struct bts_action ) +
( ( struct bts_action * ) ptr ) - > size ;
}
out_rel_fw :
/* fw download complete */
release_firmware ( fw ) ;
return err ;
}
2017-12-13 00:59:16 +03:00
static int ll_set_bdaddr ( struct hci_dev * hdev , const bdaddr_t * bdaddr )
{
bdaddr_t bdaddr_swapped ;
struct sk_buff * skb ;
/* HCI_VS_WRITE_BD_ADDR (at least on a CC2560A chip) expects the BD
* address to be MSB first , but bdaddr_t has the convention of being
* LSB first .
*/
baswap ( & bdaddr_swapped , bdaddr ) ;
skb = __hci_cmd_sync ( hdev , HCI_VS_WRITE_BD_ADDR , sizeof ( bdaddr_t ) ,
& bdaddr_swapped , HCI_INIT_TIMEOUT ) ;
if ( ! IS_ERR ( skb ) )
kfree_skb ( skb ) ;
return PTR_ERR_OR_ZERO ( skb ) ;
}
2017-04-13 18:03:52 +03:00
static int ll_setup ( struct hci_uart * hu )
{
int err , retry = 3 ;
struct ll_device * lldev ;
struct serdev_device * serdev = hu - > serdev ;
u32 speed ;
if ( ! serdev )
return 0 ;
lldev = serdev_device_get_drvdata ( serdev ) ;
2017-12-13 00:59:16 +03:00
hu - > hdev - > set_bdaddr = ll_set_bdaddr ;
2017-04-13 18:03:52 +03:00
serdev_device_set_flow_control ( serdev , true ) ;
do {
2017-12-03 05:43:55 +03:00
/* Reset the Bluetooth device */
2017-04-13 18:03:52 +03:00
gpiod_set_value_cansleep ( lldev - > enable_gpio , 0 ) ;
msleep ( 5 ) ;
gpiod_set_value_cansleep ( lldev - > enable_gpio , 1 ) ;
2020-11-10 13:13:11 +03:00
mdelay ( 100 ) ;
2017-12-03 05:43:55 +03:00
err = serdev_device_wait_for_cts ( serdev , true , 200 ) ;
if ( err ) {
bt_dev_err ( hu - > hdev , " Failed to get CTS " ) ;
return err ;
}
2017-04-13 18:03:52 +03:00
err = download_firmware ( lldev ) ;
if ( ! err )
break ;
/* Toggle BT_EN and retry */
bt_dev_err ( hu - > hdev , " download firmware failed, retrying... " ) ;
} while ( retry - - ) ;
if ( err )
return err ;
2017-12-13 02:54:12 +03:00
/* Set BD address if one was specified at probe */
if ( ! bacmp ( & lldev - > bdaddr , BDADDR_NONE ) ) {
/* This means that there was an error getting the BD address
* during probe , so mark the device as having a bad address .
*/
set_bit ( HCI_QUIRK_INVALID_BDADDR , & hu - > hdev - > quirks ) ;
} else if ( bacmp ( & lldev - > bdaddr , BDADDR_ANY ) ) {
err = ll_set_bdaddr ( hu - > hdev , & lldev - > bdaddr ) ;
if ( err )
set_bit ( HCI_QUIRK_INVALID_BDADDR , & hu - > hdev - > quirks ) ;
}
2017-04-13 18:03:52 +03:00
/* Operational speed if any */
2019-10-02 14:46:26 +03:00
if ( hu - > oper_speed )
speed = hu - > oper_speed ;
else if ( hu - > proto - > oper_speed )
speed = hu - > proto - > oper_speed ;
else
speed = 0 ;
if ( speed ) {
__le32 speed_le = cpu_to_le32 ( speed ) ;
struct sk_buff * skb ;
2017-12-04 06:21:21 +03:00
2019-10-02 14:46:26 +03:00
skb = __hci_cmd_sync ( hu - > hdev , HCI_VS_UPDATE_UART_HCI_BAUDRATE ,
sizeof ( speed_le ) , & speed_le ,
HCI_INIT_TIMEOUT ) ;
if ( ! IS_ERR ( skb ) ) {
kfree_skb ( skb ) ;
serdev_device_set_baudrate ( serdev , speed ) ;
}
}
2017-04-13 18:03:52 +03:00
return 0 ;
}
static const struct hci_uart_proto llp ;
static int hci_ti_probe ( struct serdev_device * serdev )
{
struct hci_uart * hu ;
struct ll_device * lldev ;
2017-12-13 02:54:12 +03:00
struct nvmem_cell * bdaddr_cell ;
2017-04-13 18:03:52 +03:00
u32 max_speed = 3000000 ;
lldev = devm_kzalloc ( & serdev - > dev , sizeof ( struct ll_device ) , GFP_KERNEL ) ;
if ( ! lldev )
return - ENOMEM ;
hu = & lldev - > hu ;
serdev_device_set_drvdata ( serdev , lldev ) ;
lldev - > serdev = hu - > serdev = serdev ;
2019-06-24 00:15:48 +03:00
lldev - > enable_gpio = devm_gpiod_get_optional ( & serdev - > dev ,
" enable " ,
GPIOD_OUT_LOW ) ;
2017-04-13 18:03:52 +03:00
if ( IS_ERR ( lldev - > enable_gpio ) )
return PTR_ERR ( lldev - > enable_gpio ) ;
2017-06-07 12:08:21 +03:00
lldev - > ext_clk = devm_clk_get ( & serdev - > dev , " ext_clock " ) ;
if ( IS_ERR ( lldev - > ext_clk ) & & PTR_ERR ( lldev - > ext_clk ) ! = - ENOENT )
return PTR_ERR ( lldev - > ext_clk ) ;
2017-04-13 18:03:52 +03:00
of_property_read_u32 ( serdev - > dev . of_node , " max-speed " , & max_speed ) ;
hci_uart_set_speeds ( hu , 115200 , max_speed ) ;
2017-12-13 02:54:12 +03:00
/* optional BD address from nvram */
bdaddr_cell = nvmem_cell_get ( & serdev - > dev , " bd-address " ) ;
if ( IS_ERR ( bdaddr_cell ) ) {
int err = PTR_ERR ( bdaddr_cell ) ;
if ( err = = - EPROBE_DEFER )
return err ;
/* ENOENT means there is no matching nvmem cell and ENOSYS
* means that nvmem is not enabled in the kernel configuration .
*/
if ( err ! = - ENOENT & & err ! = - ENOSYS ) {
/* If there was some other error, give userspace a
* chance to fix the problem instead of failing to load
* the driver . Using BDADDR_NONE as a flag that is
* tested later in the setup function .
*/
dev_warn ( & serdev - > dev ,
" Failed to get \" bd-address \" nvmem cell (%d) \n " ,
err ) ;
bacpy ( & lldev - > bdaddr , BDADDR_NONE ) ;
}
} else {
bdaddr_t * bdaddr ;
size_t len ;
bdaddr = nvmem_cell_read ( bdaddr_cell , & len ) ;
nvmem_cell_put ( bdaddr_cell ) ;
if ( IS_ERR ( bdaddr ) ) {
dev_err ( & serdev - > dev , " Failed to read nvmem bd-address \n " ) ;
return PTR_ERR ( bdaddr ) ;
}
if ( len ! = sizeof ( bdaddr_t ) ) {
dev_err ( & serdev - > dev , " Invalid nvmem bd-address length \n " ) ;
kfree ( bdaddr ) ;
return - EINVAL ;
}
/* As per the device tree bindings, the value from nvmem is
* expected to be MSB first , but in the kernel it is expected
* that bdaddr_t is LSB first .
*/
baswap ( & lldev - > bdaddr , bdaddr ) ;
kfree ( bdaddr ) ;
}
2017-04-13 18:03:52 +03:00
return hci_uart_register_device ( hu , & llp ) ;
}
static void hci_ti_remove ( struct serdev_device * serdev )
{
struct ll_device * lldev = serdev_device_get_drvdata ( serdev ) ;
2017-07-08 19:37:43 +03:00
hci_uart_unregister_device ( & lldev - > hu ) ;
2017-04-13 18:03:52 +03:00
}
static const struct of_device_id hci_ti_of_match [ ] = {
2017-12-13 03:29:31 +03:00
{ . compatible = " ti,cc2560 " } ,
2017-06-08 23:58:45 +03:00
{ . compatible = " ti,wl1271-st " } ,
{ . compatible = " ti,wl1273-st " } ,
{ . compatible = " ti,wl1281-st " } ,
{ . compatible = " ti,wl1283-st " } ,
{ . compatible = " ti,wl1285-st " } ,
{ . compatible = " ti,wl1801-st " } ,
{ . compatible = " ti,wl1805-st " } ,
{ . compatible = " ti,wl1807-st " } ,
2017-04-13 18:03:52 +03:00
{ . compatible = " ti,wl1831-st " } ,
{ . compatible = " ti,wl1835-st " } ,
{ . compatible = " ti,wl1837-st " } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , hci_ti_of_match ) ;
static struct serdev_device_driver hci_ti_drv = {
. driver = {
. name = " hci-ti " ,
. of_match_table = of_match_ptr ( hci_ti_of_match ) ,
} ,
. probe = hci_ti_probe ,
. remove = hci_ti_remove ,
} ;
# else
# define ll_setup NULL
# endif
2015-04-05 08:11:43 +03:00
static const struct hci_uart_proto llp = {
2007-10-20 15:42:36 +04:00
. id = HCI_UART_LL ,
2015-04-05 08:27:34 +03:00
. name = " LL " ,
2017-04-13 18:03:52 +03:00
. setup = ll_setup ,
2007-10-20 15:42:36 +04:00
. open = ll_open ,
. close = ll_close ,
. recv = ll_recv ,
. enqueue = ll_enqueue ,
. dequeue = ll_dequeue ,
. flush = ll_flush ,
} ;
2010-07-24 09:04:44 +04:00
int __init ll_init ( void )
2007-10-20 15:42:36 +04:00
{
2017-04-13 18:03:52 +03:00
serdev_device_driver_register ( & hci_ti_drv ) ;
2015-04-05 08:27:35 +03:00
return hci_uart_register_proto ( & llp ) ;
2007-10-20 15:42:36 +04:00
}
2010-07-24 09:04:44 +04:00
int __exit ll_deinit ( void )
2007-10-20 15:42:36 +04:00
{
2017-04-13 18:03:52 +03:00
serdev_device_driver_unregister ( & hci_ti_drv ) ;
2007-10-20 15:42:36 +04:00
return hci_uart_unregister_proto ( & llp ) ;
}