MT6620: add the new driver JB2 V1.0
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_fm / mt6626 / pub / mt6626_fm_link.c
1 /* mt6626_fm_link.c
2  *
3  * (C) Copyright 2009
4  * MediaTek <www.MediaTek.com>
5  * Hongcheng <hongcheng.xia@MediaTek.com>
6  *
7  * MT6626 FM Radio Driver -- setup data link
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 #include <linux/slab.h>
24 #include <linux/version.h>
25 #include <linux/interrupt.h>
26 #include <linux/cdev.h>
27 #include <asm/uaccess.h>
28 #include <linux/i2c.h>
29
30 #include "fm_typedef.h"
31 #include "fm_dbg.h"
32 #include "fm_err.h"
33 #include "fm_stdlib.h"
34
35 #include "mt6626_fm.h"
36 #include "mt6626_fm_link.h"
37 #include "mt6626_fm_reg.h"
38
39 //these functions are defined after Linux2.6.32
40 static int fm_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
41 static int fm_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info);
42 static int fm_i2c_remove(struct i2c_client *client);
43
44
45 static const struct i2c_device_id fm_i2c_id = {MT6626_DEV, 0};
46 static unsigned short force[] = {MT6626_I2C_PORT, MT6626_SLAVE_ADDR, I2C_CLIENT_END, I2C_CLIENT_END};
47 static const unsigned short * const forces[] = {force, NULL};
48 static struct i2c_client_address_data addr_data = {
49     .forces = forces
50 };
51
52 struct i2c_driver MT6626_driver = {
53     .probe = fm_i2c_probe,
54     .remove = fm_i2c_remove,
55     .detect = fm_i2c_detect,
56     .driver.name = MT6626_DEV,
57     .id_table = &fm_i2c_id,
58     .address_data = &addr_data,
59 };
60
61 static struct i2c_client *g_client;
62
63 static int fm_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
64 {
65     int ret = 0;
66
67     WCN_DBG(FM_NTC | LINK, "%s\n", __func__);
68     g_client = client;
69
70     return ret;
71 }
72
73 static int fm_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info)
74 {
75     WCN_DBG(FM_NTC | LINK, "%s\n", __func__);
76     strcpy(info->type, MT6626_DEV);
77     return 0;
78 }
79
80 static int fm_i2c_remove(struct i2c_client *client)
81 {
82     WCN_DBG(FM_NTC | LINK, "%s\n", __func__);
83     return 0;
84 }
85
86 static struct fm_link_event *link_event;
87
88 fm_s32 fm_link_setup(void* data)
89 {
90     if (!(link_event = kzalloc(sizeof(struct fm_link_event), GFP_KERNEL))) {
91         WCN_DBG(FM_ALT | LINK, "kzalloc(fm_link_event) -ENOMEM\n");
92         return -1;
93 }
94
95     link_event->ln_event = fm_flag_event_create("ln_evt");
96
97     if (!link_event->ln_event) {
98         WCN_DBG(FM_ALT | LINK, "create mt6626_ln_event failed\n");
99         fm_free(link_event);
100         return -1;
101     }
102
103     fm_flag_event_get(link_event->ln_event);
104
105     WCN_DBG(FM_NTC | LINK, "fm link setup\n");
106     return i2c_add_driver(&MT6626_driver);
107 }
108
109 fm_s32 fm_link_release(void)
110 {
111     fm_flag_event_put(link_event->ln_event);
112     if (link_event) {
113         fm_free(link_event);
114     }
115
116     WCN_DBG(FM_NTC | LINK, "fm link release\n");
117     i2c_del_driver(&MT6626_driver);
118     return 0;
119 }
120
121 /*
122  * fm_ctrl_rx
123  * the low level func to read a rigister
124  * @addr - rigister address
125  * @val - the pointer of target buf
126  * If success, return 0; else error code
127  */
128 fm_s32 fm_ctrl_rx(fm_u8 addr, fm_u16 *val)
129 {
130     fm_s32 n;
131     fm_u8 b[2] = {0};
132
133     // first, send addr to MT6626
134     n = i2c_master_send(g_client, (fm_u8*) & addr, 1);
135
136     if (n < 0) {
137         WCN_DBG(FM_ALT | LINK, "rx 1, [addr=0x%02X] [err=%d]\n", addr, n);
138         return -1;
139     }
140
141     // second, receive two byte from MT6626
142     n = i2c_master_recv(g_client, b, 2);
143
144     if (n < 0) {
145         WCN_DBG(FM_ALT | LINK, "rx 2, [addr=0x%02X] [err=%d]\n", addr, n);
146         return -2;
147     }
148
149     *val = ((fm_u16)b[0] << 8 | (fm_u16)b[1]);
150
151     return 0;
152 }
153
154 /*
155  * fm_ctrl_tx
156  * the low level func to write a rigister
157  * @addr - rigister address
158  * @val - value will be writed in the rigister
159  * If success, return 0; else error code
160  */
161 fm_s32 fm_ctrl_tx(fm_u8 addr, fm_u16 val)
162 {
163     fm_s32 n;
164     fm_u8 b[3];
165
166     b[0] = addr;
167     b[1] = (fm_u8)(val >> 8);
168     b[2] = (fm_u8)(val & 0xFF);
169
170     n = i2c_master_send(g_client, b, 3);
171
172     if (n < 0) {
173         WCN_DBG(FM_ALT | LINK, "tx, [addr=0x%02X] [err=%d]\n", addr, n);
174         return -1;
175     }
176
177     return 0;
178 }
179
180 /*
181  * fm_cmd_tx() - send cmd to FM firmware and wait event
182  * @buf - send buffer
183  * @len - the length of cmd
184  * @mask - the event flag mask
185  * @    cnt - the retry conter
186  * @timeout - timeout per cmd
187  * Return 0, if success; error code, if failed
188  */
189 fm_s32 fm_cmd_tx(fm_u8* buf, fm_u16 len, fm_s32 mask, fm_s32 cnt, fm_s32 timeout, fm_s32(*callback)(struct fm_res_ctx* result))
190 {
191     return 0;
192 }
193
194 fm_bool fm_wait_stc_done(fm_u32 sec)
195 {
196     fm_s32 ret_time = 0;
197
198     ret_time = FM_EVENT_WAIT_TIMEOUT(link_event->ln_event, FLAG_TEST, sec);
199     if (!ret_time) {
200         WCN_DBG(FM_WAR | LINK, "wait stc done fail\n");
201         return fm_false;
202     } else {
203         WCN_DBG(FM_DBG | LINK, "wait stc done ok\n");
204     }
205
206     FM_EVENT_CLR(link_event->ln_event, FLAG_TEST);
207     return fm_true;
208 }
209
210 fm_s32 fm_event_parser(fm_s32(*rds_parser)(struct rds_rx_t*, fm_s32))
211 {
212     fm_u16 tmp_reg;
213
214     fm_ctrl_rx(FM_MAIN_INTR, &tmp_reg);
215
216     if (tmp_reg&FM_INTR_STC_DONE) {
217         //clear status flag
218         fm_ctrl_tx(FM_MAIN_INTR, tmp_reg | FM_INTR_STC_DONE);
219         FM_EVENT_SEND(link_event->ln_event, FLAG_TEST);
220     }
221
222     if (tmp_reg&FM_INTR_RDS) {
223         //clear status flag
224         fm_ctrl_tx(FM_MAIN_INTR, tmp_reg | FM_INTR_RDS);
225
226         /*Handle the RDS data that we get*/
227         if (rds_parser) {
228             rds_parser(NULL, 0); //mt6626 rds lib will get rds raw data by itself
229         } else {
230             WCN_DBG(FM_WAR | LINK, "no method to parse RDS data\n");
231         }
232     }
233
234     return 0;
235 }
236
237 fm_s32 fm_force_active_event(fm_u32 mask)
238 {
239     FM_EVENT_SEND(link_event->ln_event, FLAG_TEST);
240     return 0;
241 }
242