@@ -44,10 +44,35 @@ static const unsigned int tps6287x_voltage_range_sel[] = {
44
44
0x0 , 0x1 , 0x2 , 0x3
45
45
};
46
46
47
+ static const unsigned int tps6287x_voltage_range_prefix [] = {
48
+ 0x000 , 0x100 , 0x200 , 0x300
49
+ };
50
+
47
51
static const unsigned int tps6287x_ramp_table [] = {
48
52
10000 , 5000 , 1250 , 500
49
53
};
50
54
55
+ struct tps6287x_reg_data {
56
+ int range ;
57
+ };
58
+
59
+ static int tps6287x_best_range (struct regulator_config * config , const struct regulator_desc * desc )
60
+ {
61
+ const struct linear_range * r ;
62
+ int i ;
63
+
64
+ if (!config -> init_data -> constraints .apply_uV )
65
+ return -1 ;
66
+
67
+ for (i = 0 ; i < desc -> n_linear_ranges ; i ++ ) {
68
+ r = & desc -> linear_ranges [i ];
69
+ if (r -> min <= config -> init_data -> constraints .min_uV &&
70
+ config -> init_data -> constraints .max_uV <= linear_range_get_max_value (r ))
71
+ return i ;
72
+ }
73
+ return -1 ;
74
+ }
75
+
51
76
static int tps6287x_set_mode (struct regulator_dev * rdev , unsigned int mode )
52
77
{
53
78
unsigned int val ;
@@ -91,6 +116,28 @@ static unsigned int tps6287x_of_map_mode(unsigned int mode)
91
116
}
92
117
}
93
118
119
+ static int tps6287x_map_voltage (struct regulator_dev * rdev , int min_uV , int max_uV )
120
+ {
121
+ struct tps6287x_reg_data * data = (struct tps6287x_reg_data * )rdev -> reg_data ;
122
+ struct linear_range selected_range ;
123
+ int selector , voltage ;
124
+
125
+ if (!data || data -> range == -1 )
126
+ return regulator_map_voltage_pickable_linear_range (rdev , min_uV , max_uV );
127
+
128
+ selected_range = rdev -> desc -> linear_ranges [data -> range ];
129
+ selector = DIV_ROUND_UP (min_uV - selected_range .min , selected_range .step );
130
+ if (selector < selected_range .min_sel || selector > selected_range .max_sel )
131
+ return - EINVAL ;
132
+
133
+ selector |= tps6287x_voltage_range_prefix [data -> range ];
134
+ voltage = rdev -> desc -> ops -> list_voltage (rdev , selector );
135
+ if (voltage < min_uV || voltage > max_uV )
136
+ return - EINVAL ;
137
+
138
+ return selector ;
139
+ }
140
+
94
141
static const struct regulator_ops tps6287x_regulator_ops = {
95
142
.enable = regulator_enable_regmap ,
96
143
.disable = regulator_disable_regmap ,
@@ -100,6 +147,7 @@ static const struct regulator_ops tps6287x_regulator_ops = {
100
147
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap ,
101
148
.set_voltage_sel = regulator_set_voltage_sel_pickable_regmap ,
102
149
.list_voltage = regulator_list_voltage_pickable_linear_range ,
150
+ .map_voltage = tps6287x_map_voltage ,
103
151
.set_ramp_delay = regulator_set_ramp_delay_regmap ,
104
152
};
105
153
@@ -130,8 +178,14 @@ static int tps6287x_i2c_probe(struct i2c_client *i2c)
130
178
{
131
179
struct device * dev = & i2c -> dev ;
132
180
struct regulator_config config = {};
181
+ struct tps6287x_reg_data * reg_data ;
133
182
struct regulator_dev * rdev ;
134
183
184
+ reg_data = devm_kzalloc (dev , sizeof (struct tps6287x_reg_data ), GFP_KERNEL );
185
+
186
+ if (!reg_data )
187
+ return - ENOMEM ;
188
+
135
189
config .regmap = devm_regmap_init_i2c (i2c , & tps6287x_regmap_config );
136
190
if (IS_ERR (config .regmap )) {
137
191
dev_err (dev , "Failed to init i2c\n" );
@@ -143,12 +197,15 @@ static int tps6287x_i2c_probe(struct i2c_client *i2c)
143
197
config .init_data = of_get_regulator_init_data (dev , dev -> of_node ,
144
198
& tps6287x_reg );
145
199
200
+ reg_data -> range = tps6287x_best_range (& config , & tps6287x_reg );
201
+
146
202
rdev = devm_regulator_register (dev , & tps6287x_reg , & config );
147
203
if (IS_ERR (rdev )) {
148
204
dev_err (dev , "Failed to register regulator\n" );
149
205
return PTR_ERR (rdev );
150
206
}
151
207
208
+ rdev -> reg_data = (void * )reg_data ;
152
209
dev_dbg (dev , "Probed regulator\n" );
153
210
154
211
return 0 ;
0 commit comments