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
|
/*
* Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
/*!
* @file max8660.c
* @brief Driver for max8660
*
* @ingroup pmic
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/proc_fs.h>
#include <linux/i2c.h>
#include <linux/mfd/mc9s08dz60/pmic.h>
#include <asm/uaccess.h>
#include "mcu_pmic_core.h"
#include "max8660.h"
/* I2C bus id and device address of mcu */
#define I2C1_BUS 0
#define MAX8660_I2C_ADDR 0x68
static struct i2c_client *max8660_i2c_client;
/* reg names for max8660
REG_MAX8660_OUTPUT_ENABLE_1,
REG_MAX8660_OUTPUT_ENABLE_2,
REG_MAX8660_VOLT__CHANGE_1,
REG_MAX8660_V3_TARGET_VOLT_1,
REG_MAX8660_V3_TARGET_VOLT_2,
REG_MAX8660_V4_TARGET_VOLT_1,
REG_MAX8660_V4_TARGET_VOLT_2,
REG_MAX8660_V5_TARGET_VOLT_1,
REG_MAX8660_V5_TARGET_VOLT_2,
REG_MAX8660_V6V7_TARGET_VOLT,
REG_MAX8660_FORCE_PWM
*/
/* save down the reg values for the device is write only */
static u8 max8660_reg_value_table[] = {
0x0, 0x0, 0x0, 0x17, 0x17, 0x1F, 0x1F, 0x04, 0x04, 0x0, 0x0
};
static int max8660_dev_present;
int is_max8660_present(void)
{
return max8660_dev_present;
}
int max8660_get_buffered_reg_val(int reg_name, u8 *value)
{
if (!max8660_dev_present)
return -1;
/* outof range */
if (reg_name < REG_MAX8660_OUTPUT_ENABLE_1
|| reg_name > REG_MAX8660_FORCE_PWM)
return -1;
*value =
max8660_reg_value_table[reg_name - REG_MAX8660_OUTPUT_ENABLE_1];
return 0;
}
int max8660_save_buffered_reg_val(int reg_name, u8 value)
{
/* outof range */
if (reg_name < REG_MAX8660_OUTPUT_ENABLE_1
|| reg_name > REG_MAX8660_FORCE_PWM)
return -1;
max8660_reg_value_table[reg_name - REG_MAX8660_OUTPUT_ENABLE_1] = value;
return 0;
}
int max8660_write_reg(u8 reg, u8 value)
{
if (max8660_dev_present && (i2c_smbus_write_byte_data(
max8660_i2c_client, reg, value) >= 0))
return 0;
return -1;
}
/*!
* max8660 I2C attach function
*
* @param adapter struct i2c_client *
* @return 0 for max8660 successfully detected
*/
static int max8660_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int retval;
max8660_i2c_client = client;
retval = i2c_smbus_write_byte_data(max8660_i2c_client,
MAX8660_OUTPUT_ENABLE_1, 0);
if (retval == 0) {
max8660_dev_present = 1;
pr_info("max8660 probed !\n");
} else {
max8660_dev_present = 0;
pr_info("max8660 not detected!\n");
}
return retval;
}
/*!
* max8660 I2C detach function
*
* @param client struct i2c_client *
* @return 0
*/
static int max8660_remove(struct i2c_client *client)
{
return 0;
}
static const struct i2c_device_id max8660_id[] = {
{ "max8660", 0 },
{},
};
MODULE_DEVICE_TABLE(i2c, max8660_id);
static struct i2c_driver max8660_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "max8660",},
.probe = max8660_probe,
.remove = max8660_remove,
.id_table = max8660_id,
};
/* called by pmic core when init*/
int max8660_init(void)
{
int err;
err = i2c_add_driver(&max8660_i2c_driver);
return err;
}
void max8660_exit(void)
{
i2c_del_driver(&max8660_i2c_driver);
}
|