aboutsummaryrefslogtreecommitdiff
path: root/drivers/nfc/nfc-nci.h
blob: 398fa3f6a4b01cbeabd614698a64ce06e4353ff0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __NFC_NCI_H
#define __NFC_NCI_H

#include <linux/i2c.h>
#include <linux/types.h>
#include <linux/version.h>

#include <linux/semaphore.h>
#include <linux/completion.h>

#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>

struct nfc_device {
	struct cdev cdev;
	struct class *char_class;
};

enum ehandler_mode {
	UNSOLICITED_MODE = 0,
	SOLICITED_MODE,
	UNSOLICITED_FTM_RAW_MODE,
	SOLICITED_FTM_RAW_MODE
};

enum ekernel_logging_mode {
	LEVEL_0 = 0,	/* For Basic Comms, such asNCI TX/TX to NFCC */
	LEVEL_1,	/* Other Debug e.g. Notifications, ISR hit, etc ..*/
	LEVEL_2,
	LEVEL_3,
	LEVEL_4,
	LEVEL_5
};

struct devicemode {
	enum ehandler_mode	handle_flavour;
} tdevicemode;

#define NFC_DRIVER_NAME		"nfc-nci"
#define NFC_I2C_DRIVER_NAME		"NCI NFC I2C Interface",

#define NCI_I2C_SLAVE	(0x2C)
#define NFC_I2C_BUS	3	/* 6, 10, 4, 5 */
#define NFC_SET_PWR	_IOW(0xE9, 0x01, unsigned int)
#define NFCC_MODE	_IOW(0xE9, 0x02, unsigned int)
#define NFC_KERNEL_LOGGING_MODE		_IOW(0xE9, 0x03, unsigned int)
#define SET_RX_BLOCK	_IOW(0xE9, 0x04, unsigned int)
#define SET_EMULATOR_TEST_POINT		_IOW(0xE9, 0x05, unsigned int)
#define NFCC_VERSION				_IOW(0xE9, 0x08, unsigned int)
#define NFC_GET_EFUSE				_IOW(0xE9, 0x09, unsigned int)
#define NFCC_INITIAL_CORE_RESET_NTF		_IOW(0xE9, 0x10, unsigned int)

#define NFC_MAX_I2C_TRANSFER	(0x0400)
#define NFC_MSG_MAX_SIZE	(0x21)

#define NFC_RX_BUFFER_CNT_START		(0x0)

#define NFC_RX_BUFFER_BLOCK_SIZE	(0x120)	/* Bytes per Block */
#define NFC_RX_BUFFER_PAGE_SIZE		(0x1000)	/* Page size Bytes */
#define NFC_RX_BUFFER_PAGES		(0x8)
#define NFC_RX_ORDER_FREE_PAGES	(0x3)	/* Free 8 Pages */

/* The total no. of Blocks */
#define NFC_RX_BUFFER_CNT_LIMIT		(unsigned short)(	\
						(		\
						((NFC_RX_BUFFER_PAGE_SIZE) *\
						(NFC_RX_BUFFER_PAGES))/\
						(NFC_RX_BUFFER_BLOCK_SIZE)\
						)		\
						)		\

#define PAYLOAD_HEADER_LENGTH		(0x3)
#define PAYLOAD_LENGTH_MAX		(256)
#define BYTE				(0x8)
#define NCI_IDENTIFIER			(0x10)

/** Power Management Related **/

#define NFCC_WAKE				(0x01)
#define NFCC_SLEEP				(0x00)

#define XTAL_CLOCK				(0X00)
#define REFERENCE_CLOCK			(0X01)

/* LDO Trim Settings */
#define IPTAT_TRIM			(0x1F)
#define V1P1_TRIM			(0x0F)
#define V1P8_TRIM			(0x0F)
#define VBATT_OK_THRESHOLD		(0x07)

#define PWR_EN		(0x08)		/* Enable 1.1V LDO Regulator */
#define LS_EN		(0x04)		/* Enable 1.1V->1.8V Level Shifters */

/* Write '1' to cause wake event to NFCC. If set NFCC will not go to SLEEP */
#define NCI_WAKE	(0x02)

#define NCI_ENA		(0x01)		/* Write '1' to enable PLL */
#define FREQ_SEL	(0x00)		/* XO Frequency Select */
#define FREQ_SEL_13	(0x00)		/* XO Frequency Select = 13.56MHz */
#define FREQ_SEL_19	(0x01)		/* XO Frequency Select = 19.20 MHz */
#define FREQ_SEL_26	(0x02)		/* XO Frequency Select = 26.00 MHz */
#define FREQ_SEL_27	(0x03)		/* XO Frequency Select = 27.12 MHz */
#define FREQ_SEL_37	(0x04)		/* XO Frequency Select = 37.40 MHz */
#define FREQ_SEL_38	(0x05)		/* XO Frequency Select = 38.40 MHz */
#define FREQ_SEL_40	(0x06)		/* XO Frequency Select = 40.00 MHz */
#define FREQ_SEL_48	(0x07)		/* XO Frequency Select = 48.00 MHz */
#define FREQ_SEL_27	(0x03)		/* XO Frequency Select */


#define QUALIFY_REFCLK	(0x80)
#define QUALIFY_OSC	(0x40)
#define LOCALBIASXTAL	(0x20)
#define BIAS2X_FORCE	(0x10)
#define BIAS2X		(0x08)
#define LBIAS2X	(0x04)
#define SMALLRF	(0x02)
#define SMALLRBIAS	(0x01)

/* Select as appropriate */
#define CRYSTAL_OSC	((QUALIFY_REFCLK) | (QUALIFY_OSC) |	\
			(LOCALBIASXTAL) | (BIAS2X_FORCE) |	\
			(BIAS2X) | (LBIAS2X) | (SMALLRF) | (SMALLRBIAS))

#define CDACIN		(0x3F)	/* Tuning range for load capacitor at X1*/
#define CDACOUT		(0x3F)	/* Tuning range for load capacitor at X2*/

#define RAW(reg, value)		(raw_##reg[1] = value)

/* Logging macro with threshold control */
#define PRINTK(LEVEL, THRESHOLD, pString, ...)		(	\
		if (LEVEL > THRESHOLD) {			\
			pr_info(pString, ##__VA_ARGS__);		\
		}						\
							)

/* board config */
struct nfc_platform_data {
	int (*request_resources) (struct i2c_client *client);
	void (*free_resources) (void);
	void (*enable) (int fw);
	int (*test) (void);
	void (*disable) (void);
};
/*
 * Internal NFCC Hardware states. At present these may not be possible to
 * detect in software as possibly no power when
 * in monitor state! Also, need to detect DISABLE control GPIO from PMIC.
 */
enum nfcc_hardware_state {
	NFCC_STATE_MONITOR,	/* VBAT < h/w Critcal Voltage */
	/* VBAT > H/W Critical Voltage;
	Lowest Power Mode - DISABLE = 1; only
	possible when phone is ON */
	NFCC_STATE_HPD,
	/* VBAT > H/W Critical Voltage; DISABLE = 0;
	Only possible when phone is ON */
	NFCC_STSTE_ULPM,
	/* VBAT > H/W Critical Voltage; DISABLE = 0;
	Powered by PMIC & VBAT; 1.8V I/O supply on; VDDPX available, boot is
	initiated by host over I2C */
	NFCC_STATE_NORMAL_REGION1,
	/* VBAT > H/W Critical Voltage; DISABLE = 0;
	Powered by VBAT; 1.8V I/O supply on; VDDPX available, boot is initiated
	by host over I2C */
	NFCC_STATE_NORMAL_REGION2,
};

/* We assume here that VBATT > h/w Critical Voltage */
enum nfcc_state {
	/* Assume In ULPM state, ready for initialisation, cannot detect for
	Monitor or HPD states */
	NFCC_STATE_COLD,
	/* (VDDPX==1) && (Following I2C initialisation). In Region 1 or Region2
	state WAKE */
	NFCC_STATE_NORMAL_WAKE,
	/* (VDDPX==1) && (Following I2C initialisation). In Region 1 or Region2
	state SLEEP */
	NFCC_STATE_NORMAL_SLEEP,
};


enum nfcc_irq {
	NFCC_NO_INT,
	NFCC_INT,
};

enum nfcc_initial_core_reset_ntf {
	TIMEDOUT_INITIAL_CORE_RESET_NTF = 0, /* 0*/
	ARRIVED_INITIAL_CORE_RESET_NTF, /* 1 */
	DEFAULT_INITIAL_CORE_RESET_NTF, /*2*/
};

struct nfc_info {
	struct	miscdevice			miscdev;
	struct	i2c_client			*i2c_dev;
	struct	regulator_bulk_data		regs[3];
	enum	nfcc_state			state;
	wait_queue_head_t			read_wait;
	loff_t					read_offset;
	struct	mutex				read_mutex;
	struct	mutex				mutex;
	u8					*buf;
	size_t					buflen;
	spinlock_t				irq_enabled_lock;
	unsigned int				count_irq;
	enum	nfcc_irq			read_irq;
};


struct nfc_i2c_platform_data {
	unsigned int	nfc_irq_gpio;
	unsigned int	nfc_clk_en_gpio;
	unsigned int	dis_gpio;
	unsigned int	irq_gpio;
	unsigned int	ven_gpio;
	unsigned int	firm_gpio;
	unsigned int	reg;
};
#endif