summaryrefslogtreecommitdiff
path: root/drivers/staging/nvec/nvec.h
blob: 544080259e2c52fd14bb9a3457d3fba11a0b97a6 (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
/*
 * NVEC: NVIDIA compliant embedded controller interface
 *
 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.launchpad.net>
 *
 * Authors:  Pierre-Hugues Husson <phhusson@free.fr>
 *           Ilya Petrov <ilya.muromec@gmail.com>
 *           Marc Dietrich <marvin24@gmx.de>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 */

#ifndef __LINUX_MFD_NVEC
#define __LINUX_MFD_NVEC

#include <linux/atomic.h>
#include <linux/notifier.h>
#include <linux/semaphore.h>

/* NVEC_POOL_SIZE - Size of the pool in &struct nvec_msg */
#define NVEC_POOL_SIZE	64

typedef enum {
	NVEC_2BYTES,
	NVEC_3BYTES,
	NVEC_VAR_SIZE
} nvec_size;

typedef enum {
	NOT_REALLY,
	YES,
	NOT_AT_ALL,
} how_care;

typedef enum {
	NVEC_SYS = 1,
	NVEC_BAT,
	NVEC_KBD = 5,
	NVEC_PS2,
	NVEC_CNTL,
	NVEC_KB_EVT = 0x80,
	NVEC_PS2_EVT
} nvec_event;

typedef enum {
	NVEC_WAIT,
	NVEC_READ,
	NVEC_WRITE
} nvec_state;

struct nvec_msg {
	unsigned char *data;
	unsigned short size;
	unsigned short pos;
	struct list_head node;
	atomic_t used;
};

struct nvec_subdev {
	const char *name;
	void *platform_data;
	int id;
};

struct nvec_platform_data {
	int i2c_addr;
	int gpio;
};

struct nvec_chip {
	struct device *dev;
	int gpio;
	int irq;
	int i2c_addr;
	void __iomem *base;
	struct clk *i2c_clk;
	nvec_state state;
	struct atomic_notifier_head notifier_list;
	struct list_head rx_data, tx_data;
	struct notifier_block nvec_status_notifier;
	struct work_struct rx_work, tx_work;
	struct nvec_msg *rx, *tx;
	struct nvec_msg msg_pool[NVEC_POOL_SIZE];

	/* sync write stuff */
	struct semaphore sync_write_mutex;
	struct completion sync_write;
	u16 sync_write_pending;
	struct nvec_msg *last_sync_msg;
};

extern void nvec_write_async(struct nvec_chip *nvec, const unsigned char *data,
			     short size);

extern int nvec_register_notifier(struct nvec_chip *nvec,
				  struct notifier_block *nb,
				  unsigned int events);

extern int nvec_unregister_notifier(struct device *dev,
				    struct notifier_block *nb,
				    unsigned int events);

const char *nvec_send_msg(unsigned char *src, unsigned char *dst_size,
			  how_care care_resp,
			  void (*rt_handler) (unsigned char *data));

#define I2C_CNFG			0x00
#define I2C_CNFG_PACKET_MODE_EN		(1<<10)
#define I2C_CNFG_NEW_MASTER_SFM		(1<<11)
#define I2C_CNFG_DEBOUNCE_CNT_SHIFT	12

#define I2C_SL_CNFG		0x20
#define I2C_SL_NEWL		(1<<2)
#define I2C_SL_NACK		(1<<1)
#define I2C_SL_RESP		(1<<0)
#define I2C_SL_IRQ		(1<<3)
#define END_TRANS		(1<<4)
#define RCVD			(1<<2)
#define RNW			(1<<1)

#define I2C_SL_RCVD		0x24
#define I2C_SL_STATUS		0x28
#define I2C_SL_ADDR1		0x2c
#define I2C_SL_ADDR2		0x30
#define I2C_SL_DELAY_COUNT	0x3c

#endif