stereo solution first commit
[tas2555sw-android/tas2555-android-device-driver-stereo.git] / tas2555-i2c.c
1 /*
2 ** =============================================================================
3 ** Copyright (c) 2016  Texas Instruments Inc.
4 **
5 ** This program is free software; you can redistribute it and/or modify it under
6 ** the terms of the GNU General Public License as published by the Free Software 
7 ** Foundation; version 2.
8 **
9 ** This program is distributed in the hope that it will be useful, but WITHOUT
10 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 **
13 ** You should have received a copy of the GNU General Public License along with
14 ** this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15 ** Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 **
17 ** File:
18 **     tas2555-regmap.c
19 **
20 ** Description:
21 **     I2C driver with regmap for Texas Instruments TAS2555 High Performance 4W Smart Amplifier
22 **
23 ** =============================================================================
24 */
26 #ifdef CONFIG_TAS2555_I2C_STEREO
28 #define DEBUG
29 #include <linux/module.h>
30 #include <linux/moduleparam.h>
31 #include <linux/init.h>
32 #include <linux/delay.h>
33 #include <linux/pm.h>
34 #include <linux/i2c.h>
35 #include <linux/gpio.h>
36 #include <linux/regulator/consumer.h>
37 #include <linux/firmware.h>
38 #include <linux/regmap.h>
39 #include <linux/of.h>
40 #include <linux/of_gpio.h>
41 #include <linux/slab.h>
42 #include <linux/syscalls.h>
43 #include <linux/fcntl.h>
44 #include <asm/uaccess.h>
45 #include "tas2555.h"
46 #include "tas2555-core.h"
48 #ifdef CONFIG_TAS2555_CODEC_STEREO
49 #include "tas2555-codec.h"
50 #endif
52 #ifdef CONFIG_TAS2555_MISC_STEREO
53 #include "tas2555-misc.h"
54 #endif
56 #define ENABLE_TILOAD                   //only enable this for in-system tuning or debug, not for production systems
57 #ifdef ENABLE_TILOAD
58 #include "tiload.h"
59 #endif
61 static int tas2555_i2c_write_device(
62         struct tas2555_priv *pTAS2555,
63         unsigned char addr, 
64         unsigned char reg, 
65         unsigned char value)
66 {
67         int ret;
68         u8 data[2];
69         struct i2c_msg *msg = &pTAS2555->xfer_msg[0];
71         msg->addr = addr;
72         msg->len = 2;
73         msg->flags = 0;
74         data[0] = reg;
75         data[1] = value;
76         msg->buf = data;
77         ret = i2c_transfer(
78                 pTAS2555->client->adapter, 
79                 pTAS2555->xfer_msg, 1);
80         /* Try again if the write fails */
81         if (ret != 1) {
82                 ret = i2c_transfer(
83                         pTAS2555->client->adapter, 
84                         pTAS2555->xfer_msg, 1);
85                 if (ret != 1) {
86                         dev_err(pTAS2555->dev, "failed to write the device, %d\n", ret);
87                         return ret;
88                 }
89         }
90         
91         return 0;
92 }
94 int tas2555_i2c_read_device(    
95         struct tas2555_priv *pTAS2555,
96         unsigned char addr, 
97         unsigned char reg, 
98         unsigned char *p_value)
99 {
100         struct i2c_msg *msg;
101         int ret = 0;
103         msg = &pTAS2555->xfer_msg[0];
104         msg->addr = addr;
105         msg->len = 1;
106         msg->flags = 0;
107         msg->buf = &reg;
108         msg = &pTAS2555->xfer_msg[1];
109         msg->addr = addr;
110         msg->len = 1;
111         msg->flags = I2C_M_RD;
112         msg->buf = p_value;
113         ret = i2c_transfer(pTAS2555->client->adapter,
114                         pTAS2555->xfer_msg, 2);
116         /* Try again if read fails first time */
117         if (ret != 2) {
118                 ret = i2c_transfer(pTAS2555->client->adapter,
119                                    pTAS2555->xfer_msg, 2);
120                 if (ret != 2) {
121                         dev_err(pTAS2555->dev, "failed to read the device, %d\n", ret);
122                         return ret;
123                 }
124         }
125         
126         return 0;
129 static int tas2555_change_book_page(
130         struct tas2555_priv *pTAS2555, 
131         enum channel chn,
132         int nBook,
133         int nPage)
135         int nResult = 0;
136         
137         if(chn&channel_left){
138                 if(pTAS2555->mnLCurrentBook == nBook){
139                         if(pTAS2555->mnLCurrentPage != nPage){
140                                 nResult = tas2555_i2c_write_device(pTAS2555, pTAS2555->mnLAddr, TAS2555_BOOKCTL_PAGE, nPage);
141                                 if(nResult >=0 )
142                                         pTAS2555->mnLCurrentPage = nPage;
143                         }
144                 }else{
145                         nResult = tas2555_i2c_write_device(pTAS2555, pTAS2555->mnLAddr, TAS2555_BOOKCTL_PAGE, 0);
146                         if(nResult >=0){
147                                 pTAS2555->mnLCurrentPage = 0;
148                                 nResult = tas2555_i2c_write_device(pTAS2555, pTAS2555->mnLAddr, TAS2555_BOOKCTL_REG, nBook);
149                                 pTAS2555->mnLCurrentBook = nBook;
150                                 if(nPage != 0){
151                                         tas2555_i2c_write_device(pTAS2555, pTAS2555->mnLAddr, TAS2555_BOOKCTL_PAGE, nPage);
152                                         pTAS2555->mnLCurrentPage = nPage;
153                                 }
154                         }
155                 }
156         }
158         if(chn&channel_right){
159                 if(pTAS2555->mnRCurrentBook == nBook){
160                         if(pTAS2555->mnRCurrentPage != nPage){
161                                 nResult = tas2555_i2c_write_device(pTAS2555, pTAS2555->mnRAddr, TAS2555_BOOKCTL_PAGE, nPage);
162                                 if(nResult >=0 )
163                                         pTAS2555->mnRCurrentPage = nPage;
164                         }
165                 }else{
166                         nResult = tas2555_i2c_write_device(pTAS2555, pTAS2555->mnRAddr, TAS2555_BOOKCTL_PAGE, 0);
167                         if(nResult >=0){
168                                 pTAS2555->mnRCurrentPage = 0;
169                                 nResult = tas2555_i2c_write_device(pTAS2555, pTAS2555->mnRAddr, TAS2555_BOOKCTL_REG, nBook);
170                                 pTAS2555->mnRCurrentBook = nBook;
171                                 if(nPage != 0){
172                                         tas2555_i2c_write_device(pTAS2555, pTAS2555->mnRAddr, TAS2555_BOOKCTL_PAGE, nPage);
173                                         pTAS2555->mnRCurrentPage = nPage;
174                                 }
175                         }
176                 }
177         }       
178         return nResult;
181 static int tas2555_dev_read(
182         struct tas2555_priv *pTAS2555,
183         enum channel chn,
184         unsigned int nRegister, 
185         unsigned int *pValue)
187         int nResult = 0;
188         unsigned char Value = 0;
190         mutex_lock(&pTAS2555->dev_lock);        
191         
192         if (pTAS2555->mbTILoadActive) {
193                 if (!(nRegister & 0x80000000)){
194                         mutex_unlock(&pTAS2555->dev_lock);
195                         return 0;                       // let only reads from TILoad pass.
196                 }
197                 nRegister &= ~0x80000000;
198         }
200         nResult = tas2555_change_book_page(pTAS2555, 
201                                                         chn, 
202                                                         TAS2555_BOOK_ID(nRegister),
203                                                         TAS2555_PAGE_ID(nRegister));
204         if(nResult >=0){
205                 if(chn == channel_left){
206                         nResult = tas2555_i2c_read_device(pTAS2555, pTAS2555->mnLAddr, TAS2555_PAGE_REG(nRegister), &Value);
207                 }else if(chn == channel_right){
208                         nResult = tas2555_i2c_read_device(pTAS2555, pTAS2555->mnRAddr, TAS2555_PAGE_REG(nRegister), &Value);
209                 }else{
210                         dev_err(pTAS2555->dev, "read chn ERROR %d\n", chn);
211                         nResult = -1;
212                 }
213                 
214                 if(nResult>=0) *pValue = Value;
215         }
216         mutex_unlock(&pTAS2555->dev_lock);
217         return nResult;
220 static int tas2555_dev_write(
221         struct tas2555_priv *pTAS2555,
222         enum channel chn,
223         unsigned int nRegister, 
224         unsigned int nValue)
226         int nResult = 0;
227         
228         mutex_lock(&pTAS2555->dev_lock);
229         if ((nRegister == 0xAFFEAFFE) && (nValue == 0xBABEBABE)) {
230                 pTAS2555->mbTILoadActive = true;
231                 mutex_unlock(&pTAS2555->dev_lock);
232                 return 0;
233         }
235         if ((nRegister == 0xBABEBABE) && (nValue == 0xAFFEAFFE)) {
236                 pTAS2555->mbTILoadActive = false;
237                 mutex_unlock(&pTAS2555->dev_lock);
238                 return 0;
239         }
241         if (pTAS2555->mbTILoadActive) {
242                 if (!(nRegister & 0x80000000)){
243                         mutex_unlock(&pTAS2555->dev_lock);
244                         return 0;                       // let only writes from TILoad pass.
245                 }
246                 nRegister &= ~0x80000000;
247         }
249         nResult = tas2555_change_book_page(pTAS2555, 
250                                                         chn, 
251                                                         TAS2555_BOOK_ID(nRegister),
252                                                         TAS2555_PAGE_ID(nRegister));
254         if(nResult >= 0){
255                 if(chn & channel_left){
256                         nResult = tas2555_i2c_write_device(pTAS2555, pTAS2555->mnLAddr, TAS2555_PAGE_REG(nRegister), nValue);
257                 }
258                 
259                 if(chn & channel_right){
260                         nResult = tas2555_i2c_write_device(pTAS2555, pTAS2555->mnRAddr, TAS2555_PAGE_REG(nRegister), nValue);
261                 }       
262         }
263         
264         mutex_unlock(&pTAS2555->dev_lock);              
265         
266         return nResult;
269 static int tas2555_dev_bulk_read(
270         struct tas2555_priv *pTAS2555,
271         enum channel chn,
272         unsigned int nRegister, 
273         u8 * pData, 
274         unsigned int nLength)
276         int nResult = 0, i;
277         unsigned char reg = 0;
278         unsigned char Addr = 0;
279         
280         mutex_lock(&pTAS2555->dev_lock);
281         if (pTAS2555->mbTILoadActive) {
282                 if (!(nRegister & 0x80000000)){
283                         mutex_unlock(&pTAS2555->dev_lock);
284                         return 0;                       // let only writes from TILoad pass.
285                 }
286                 nRegister &= ~0x80000000;
287         }
289         nResult = tas2555_change_book_page(pTAS2555, 
290                                                                         chn,
291                                                                         TAS2555_BOOK_ID(nRegister),
292                                                                         TAS2555_PAGE_ID(nRegister));
293         if(nResult >= 0){
294                 reg = TAS2555_PAGE_REG(nRegister);              
295                 if(chn == channel_left){                        
296                         Addr = pTAS2555->mnLAddr;
297                 }else if(chn == channel_right){
298                         Addr = pTAS2555->mnRAddr;
299                 }else{
300                         dev_err(pTAS2555->dev, "bulk read chn ERROR %d\n", chn);
301                         nResult = -1;
302                 }
303                 
304                 if(nResult >= 0){
305                         for(i = 0; i < nLength; i++){
306                                 nResult = tas2555_i2c_read_device(pTAS2555, Addr, reg+i, &pData[i]);
307                         }                       
308                 }
309         }
310                                                                         
311         mutex_unlock(&pTAS2555->dev_lock);      
313         return nResult;
316 static int tas2555_dev_bulk_write(
317         struct tas2555_priv *pTAS2555,
318         enum channel chn,
319         unsigned int nRegister, 
320         u8 * pData, 
321         unsigned int nLength)
323         int nResult = 0;
324         int i;
325         unsigned char reg = 0;
326         
327         mutex_lock(&pTAS2555->dev_lock);
328         if (pTAS2555->mbTILoadActive) {
329                 if (!(nRegister & 0x80000000)){
330                         mutex_unlock(&pTAS2555->dev_lock);
331                         return 0;                       // let only writes from TILoad pass.
332                 }
333                 nRegister &= ~0x80000000;
334         }
336         nResult = tas2555_change_book_page(
337                 pTAS2555, 
338                 chn,
339                 TAS2555_BOOK_ID(nRegister),
340                 TAS2555_PAGE_ID(nRegister));
341                 
342         if(nResult >=0){
343                 reg = TAS2555_PAGE_REG(nRegister);      
344                 if(chn & channel_left){
345                         for(i = 0; i < nLength; i++){
346                                 tas2555_i2c_write_device(
347                                         pTAS2555, 
348                                         pTAS2555->mnLAddr, 
349                                         reg+i, 
350                                         pData[i]);
351                         }
352                 }
353                 
354                 if(chn & channel_right){
355                         for(i = 0; i < nLength; i++){
356                                 tas2555_i2c_write_device(
357                                         pTAS2555, 
358                                         pTAS2555->mnRAddr, 
359                                         reg+i, 
360                                         pData[i]);
361                         }
362                 }
363         }
364         mutex_unlock(&pTAS2555->dev_lock);              
365         
366         return nResult;
369 static int tas2555_dev_update_bits(
370         struct tas2555_priv *pTAS2555,
371         enum channel chn,
372         unsigned int nRegister, 
373         unsigned int nMask, 
374         unsigned int nValue)
376         int nResult = 0;
377         unsigned char temp = 0;
378         
379         mutex_lock(&pTAS2555->dev_lock);
380         
381         if (pTAS2555->mbTILoadActive) {
382                 if (!(nRegister & 0x80000000)){
383                         mutex_unlock(&pTAS2555->dev_lock);
384                         return 0;                       // let only writes from TILoad pass.
385                 }
386                 nRegister &= ~0x80000000;
387         }
388         
389         nResult = tas2555_change_book_page(
390                 pTAS2555,
391                 chn,
392                 TAS2555_BOOK_ID(nRegister),
393                 TAS2555_PAGE_ID(nRegister));
394         
395         if(nResult>=0){
396                 if(chn&channel_left){
397                         tas2555_i2c_read_device(pTAS2555, pTAS2555->mnLAddr, TAS2555_PAGE_REG(nRegister), &temp);
398                         if((temp&nMask)!=(nValue&nMask)){
399                                 temp &= ~nMask;
400                                 temp |= (nValue&nMask);
401                                 tas2555_i2c_write_device(pTAS2555, pTAS2555->mnLAddr, TAS2555_PAGE_REG(nRegister), temp);
402                         }
403                 }
404                 
405                 if(chn&channel_right){
406                         tas2555_i2c_read_device(pTAS2555, pTAS2555->mnRAddr, TAS2555_PAGE_REG(nRegister), &temp);
407                         if((temp&nMask)!=(nValue&nMask)){
408                                 temp &= ~nMask;
409                                 temp |= (nValue&nMask);
410                                 tas2555_i2c_write_device(pTAS2555, pTAS2555->mnRAddr, TAS2555_PAGE_REG(nRegister), temp);
411                         }
412                 }       
413         }
414                 
415         mutex_unlock(&pTAS2555->dev_lock);              
416         return nResult;
419 static int tas2555_i2c_probe(struct i2c_client *pClient,
420         const struct i2c_device_id *pID)
422         struct tas2555_priv *pTAS2555;
423         int nResult;
424         unsigned int nValue = 0;
426         dev_info(&pClient->dev, "%s enter\n", __FUNCTION__);
427                 
428         pTAS2555 = devm_kzalloc(&pClient->dev, sizeof(struct tas2555_priv), GFP_KERNEL);
429         if (!pTAS2555){
430                 dev_err(&pClient->dev, " -ENOMEM\n");
431                 return -ENOMEM;
432         }
433         
434         pTAS2555->client = pClient;
435         pTAS2555->dev = &pClient->dev;
436         i2c_set_clientdata(pClient, pTAS2555);
437         dev_set_drvdata(&pClient->dev, pTAS2555);       
438         mutex_init(&pTAS2555->dev_lock);
439         
440         nResult = tas2555_parse_dt(&pClient->dev, pTAS2555);
441         if(nResult < 0){
442                 dev_err(&pClient->dev, " dt error\n");
443                 return -EINVAL;
444         }
445         pTAS2555->mnLCurrentBook = -1;
446         pTAS2555->mnLCurrentPage = -1;
447         pTAS2555->mnRCurrentBook = -1;
448         pTAS2555->mnRCurrentPage = -1;
449         
450         /* Reset the chip */
451         nResult = tas2555_dev_write(pTAS2555, channel_both, TAS2555_SW_RESET_REG, 1);
452         if(nResult < 0){
453                 dev_err(&pClient->dev, "I2c fail, %d\n", nResult);      
454                 mutex_destroy(&pTAS2555->dev_lock);
455         }else{
456                 udelay(1000);
457                 tas2555_dev_read(pTAS2555, channel_left, TAS2555_REV_PGID_REG, &nValue);
458                 dev_info(&pClient->dev, "Left Chn, PGID=0x%x\n", nValue);
459                 tas2555_dev_read(pTAS2555, channel_right, TAS2555_REV_PGID_REG, &nValue);
460                 dev_info(&pClient->dev, "Right Chn, PGID=0x%x\n", nValue);      
461                 
462                 pTAS2555->mpFirmware = devm_kzalloc(&pClient->dev, sizeof(TFirmware), GFP_KERNEL);
463                 if (!pTAS2555->mpFirmware){
464                         dev_err(&pClient->dev, "mpFirmware ENOMEM\n");  
465                         mutex_destroy(&pTAS2555->dev_lock);
466                         return -ENOMEM;
467                 }
469                 pTAS2555->mpCalFirmware = devm_kzalloc(&pClient->dev, sizeof(TFirmware), GFP_KERNEL);
470                 if (!pTAS2555->mpCalFirmware){
471                         dev_err(&pClient->dev, "mpCalFirmware ENOMEM\n");
472                         mutex_destroy(&pTAS2555->dev_lock);                     
473                         return -ENOMEM;
474                 }
475                 
476                 pTAS2555->read = tas2555_dev_read;
477                 pTAS2555->write = tas2555_dev_write;
478                 pTAS2555->bulk_read = tas2555_dev_bulk_read;
479                 pTAS2555->bulk_write = tas2555_dev_bulk_write;
480                 pTAS2555->update_bits = tas2555_dev_update_bits;
481                 pTAS2555->set_config = tas2555_set_config;
482                 pTAS2555->set_calibration = tas2555_set_calibration;
483                 
484                 nResult = request_firmware_nowait(THIS_MODULE, 1, TAS2555_FW_NAME,
485                         pTAS2555->dev, GFP_KERNEL, pTAS2555, tas2555_fw_ready);
487 #ifdef CONFIG_TAS2555_CODEC_STEREO      
488                 tas2555_register_codec(pTAS2555);
489 #endif
491 #ifdef CONFIG_TAS2555_MISC_STEREO       
492         mutex_init(&pTAS2555->file_lock);
493         tas2555_register_misc(pTAS2555);
494 #endif
496         }
497         
498         return nResult;
501 static int tas2555_i2c_remove(struct i2c_client *pClient)
503         struct tas2555_priv *pTAS2555 = i2c_get_clientdata(pClient);
504         
505         dev_info(pTAS2555->dev, "%s\n", __FUNCTION__);
506         
507 #ifdef CONFIG_TAS2555_CODEC_STEREO              
508         tas2555_deregister_codec(pTAS2555);
509 #endif
511 #ifdef CONFIG_TAS2555_MISC_STEREO               
512         tas2555_deregister_misc(pTAS2555);
513         mutex_destroy(&pTAS2555->file_lock);
514 #endif
515         
516         return 0;
519 static const struct i2c_device_id tas2555_i2c_id[] = {
520         {"tas2555s", 0},
521         {}
522 };
524 MODULE_DEVICE_TABLE(i2c, tas2555_i2c_id);
526 #if defined(CONFIG_OF)
527 static const struct of_device_id tas2555_of_match[] = {
528         {.compatible = "ti,tas2555s"},
529         {},
530 };
532 MODULE_DEVICE_TABLE(of, tas2555_of_match);
533 #endif
535 static struct i2c_driver tas2555_i2c_driver = {
536         .driver = {
537                         .name = "tas2555s",
538                         .owner = THIS_MODULE,
539 #if defined(CONFIG_OF)
540                         .of_match_table = of_match_ptr(tas2555_of_match),
541 #endif
542                 },
543         .probe = tas2555_i2c_probe,
544         .remove = tas2555_i2c_remove,
545         .id_table = tas2555_i2c_id,
546 };
548 module_i2c_driver(tas2555_i2c_driver);
550 MODULE_AUTHOR("Texas Instruments Inc.");
551 MODULE_DESCRIPTION("TAS2555 Stereo I2C Smart Amplifier driver");
552 MODULE_LICENSE("GPLv2");
553 #endif