pinctrl-meson.c (e0cdd3a095f9a933ff74e89e5fc625e4c2f3a7f0) pinctrl-meson.c (3c910ecbdda4227abd145967774f92b1a3341493)
1// SPDX-License-Identifier: GPL-2.0
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Pin controller and GPIO driver for Amlogic Meson SoCs
4 *
5 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
6 */
7
8/*
9 * The available pins are organized in banks (A,B,C,D,E,X,Y,Z,AO,

--- 153 unchanged lines hidden (view full) ---

163 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
164
165 *groups = pc->data->funcs[selector].groups;
166 *num_groups = pc->data->funcs[selector].num_groups;
167
168 return 0;
169}
170
2/*
3 * Pin controller and GPIO driver for Amlogic Meson SoCs
4 *
5 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
6 */
7
8/*
9 * The available pins are organized in banks (A,B,C,D,E,X,Y,Z,AO,

--- 153 unchanged lines hidden (view full) ---

163 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
164
165 *groups = pc->data->funcs[selector].groups;
166 *num_groups = pc->data->funcs[selector].num_groups;
167
168 return 0;
169}
170
171static int meson_pinconf_set_gpio_bit(struct meson_pinctrl *pc,
172 unsigned int pin,
173 unsigned int reg_type,
174 bool arg)
171static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
172 unsigned long *configs, unsigned num_configs)
175{
173{
174 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
176 struct meson_bank *bank;
175 struct meson_bank *bank;
176 enum pin_config_param param;
177 unsigned int reg, bit;
177 unsigned int reg, bit;
178 int ret;
178 int i, ret;
179
180 ret = meson_get_bank(pc, pin, &bank);
181 if (ret)
182 return ret;
183
179
180 ret = meson_get_bank(pc, pin, &bank);
181 if (ret)
182 return ret;
183
184 meson_calc_reg_and_bit(bank, pin, reg_type, &reg, &bit);
185 return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
186 arg ? BIT(bit) : 0);
187}
188
189static int meson_pinconf_get_gpio_bit(struct meson_pinctrl *pc,
190 unsigned int pin,
191 unsigned int reg_type)
192{
193 struct meson_bank *bank;
194 unsigned int reg, bit, val;
195 int ret;
196
197 ret = meson_get_bank(pc, pin, &bank);
198 if (ret)
199 return ret;
200
201 meson_calc_reg_and_bit(bank, pin, reg_type, &reg, &bit);
202 ret = regmap_read(pc->reg_gpio, reg, &val);
203 if (ret)
204 return ret;
205
206 return BIT(bit) & val ? 1 : 0;
207}
208
209static int meson_pinconf_set_output(struct meson_pinctrl *pc,
210 unsigned int pin,
211 bool out)
212{
213 return meson_pinconf_set_gpio_bit(pc, pin, REG_DIR, !out);
214}
215
216static int meson_pinconf_get_output(struct meson_pinctrl *pc,
217 unsigned int pin)
218{
219 int ret = meson_pinconf_get_gpio_bit(pc, pin, REG_DIR);
220
221 if (ret < 0)
222 return ret;
223
224 return !ret;
225}
226
227static int meson_pinconf_set_drive(struct meson_pinctrl *pc,
228 unsigned int pin,
229 bool high)
230{
231 return meson_pinconf_set_gpio_bit(pc, pin, REG_OUT, high);
232}
233
234static int meson_pinconf_get_drive(struct meson_pinctrl *pc,
235 unsigned int pin)
236{
237 return meson_pinconf_get_gpio_bit(pc, pin, REG_OUT);
238}
239
240static int meson_pinconf_set_output_drive(struct meson_pinctrl *pc,
241 unsigned int pin,
242 bool high)
243{
244 int ret;
245
246 ret = meson_pinconf_set_output(pc, pin, true);
247 if (ret)
248 return ret;
249
250 return meson_pinconf_set_drive(pc, pin, high);
251}
252
253static int meson_pinconf_disable_bias(struct meson_pinctrl *pc,
254 unsigned int pin)
255{
256 struct meson_bank *bank;
257 unsigned int reg, bit = 0;
258 int ret;
259
260 ret = meson_get_bank(pc, pin, &bank);
261 if (ret)
262 return ret;
263
264 meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
265 ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), 0);
266 if (ret)
267 return ret;
268
269 return 0;
270}
271
272static int meson_pinconf_enable_bias(struct meson_pinctrl *pc, unsigned int pin,
273 bool pull_up)
274{
275 struct meson_bank *bank;
276 unsigned int reg, bit, val = 0;
277 int ret;
278
279 ret = meson_get_bank(pc, pin, &bank);
280 if (ret)
281 return ret;
282
283 meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
284 if (pull_up)
285 val = BIT(bit);
286
287 ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), val);
288 if (ret)
289 return ret;
290
291 meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
292 ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), BIT(bit));
293 if (ret)
294 return ret;
295
296 return 0;
297}
298
299static int meson_pinconf_set_drive_strength(struct meson_pinctrl *pc,
300 unsigned int pin,
301 u16 drive_strength_ua)
302{
303 struct meson_bank *bank;
304 unsigned int reg, bit, ds_val;
305 int ret;
306
307 if (!pc->reg_ds) {
308 dev_err(pc->dev, "drive-strength not supported\n");
309 return -ENOTSUPP;
310 }
311
312 ret = meson_get_bank(pc, pin, &bank);
313 if (ret)
314 return ret;
315
316 meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
317 bit = bit << 1;
318
319 if (drive_strength_ua <= 500) {
320 ds_val = MESON_PINCONF_DRV_500UA;
321 } else if (drive_strength_ua <= 2500) {
322 ds_val = MESON_PINCONF_DRV_2500UA;
323 } else if (drive_strength_ua <= 3000) {
324 ds_val = MESON_PINCONF_DRV_3000UA;
325 } else if (drive_strength_ua <= 4000) {
326 ds_val = MESON_PINCONF_DRV_4000UA;
327 } else {
328 dev_warn_once(pc->dev,
329 "pin %u: invalid drive-strength : %d , default to 4mA\n",
330 pin, drive_strength_ua);
331 ds_val = MESON_PINCONF_DRV_4000UA;
332 }
333
334 ret = regmap_update_bits(pc->reg_ds, reg, 0x3 << bit, ds_val << bit);
335 if (ret)
336 return ret;
337
338 return 0;
339}
340
341static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
342 unsigned long *configs, unsigned num_configs)
343{
344 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
345 enum pin_config_param param;
346 unsigned int arg = 0;
347 int i, ret;
348
349 for (i = 0; i < num_configs; i++) {
350 param = pinconf_to_config_param(configs[i]);
351
352 switch (param) {
184 for (i = 0; i < num_configs; i++) {
185 param = pinconf_to_config_param(configs[i]);
186
187 switch (param) {
353 case PIN_CONFIG_DRIVE_STRENGTH_UA:
354 case PIN_CONFIG_OUTPUT_ENABLE:
355 case PIN_CONFIG_OUTPUT:
356 arg = pinconf_to_config_argument(configs[i]);
357 break;
188 case PIN_CONFIG_BIAS_DISABLE:
189 dev_dbg(pc->dev, "pin %u: disable bias\n", pin);
358
190
359 default:
191 meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg,
192 &bit);
193 ret = regmap_update_bits(pc->reg_pullen, reg,
194 BIT(bit), 0);
195 if (ret)
196 return ret;
360 break;
197 break;
361 }
198 case PIN_CONFIG_BIAS_PULL_UP:
199 dev_dbg(pc->dev, "pin %u: enable pull-up\n", pin);
362
200
363 switch (param) {
364 case PIN_CONFIG_BIAS_DISABLE:
365 ret = meson_pinconf_disable_bias(pc, pin);
201 meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
202 &reg, &bit);
203 ret = regmap_update_bits(pc->reg_pullen, reg,
204 BIT(bit), BIT(bit));
205 if (ret)
206 return ret;
207
208 meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
209 ret = regmap_update_bits(pc->reg_pull, reg,
210 BIT(bit), BIT(bit));
211 if (ret)
212 return ret;
366 break;
213 break;
367 case PIN_CONFIG_BIAS_PULL_UP:
368 ret = meson_pinconf_enable_bias(pc, pin, true);
369 break;
370 case PIN_CONFIG_BIAS_PULL_DOWN:
214 case PIN_CONFIG_BIAS_PULL_DOWN:
371 ret = meson_pinconf_enable_bias(pc, pin, false);
215 dev_dbg(pc->dev, "pin %u: enable pull-down\n", pin);
216
217 meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
218 &reg, &bit);
219 ret = regmap_update_bits(pc->reg_pullen, reg,
220 BIT(bit), BIT(bit));
221 if (ret)
222 return ret;
223
224 meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
225 ret = regmap_update_bits(pc->reg_pull, reg,
226 BIT(bit), 0);
227 if (ret)
228 return ret;
372 break;
229 break;
373 case PIN_CONFIG_DRIVE_STRENGTH_UA:
374 ret = meson_pinconf_set_drive_strength(pc, pin, arg);
375 break;
376 case PIN_CONFIG_OUTPUT_ENABLE:
377 ret = meson_pinconf_set_output(pc, pin, arg);
378 break;
379 case PIN_CONFIG_OUTPUT:
380 ret = meson_pinconf_set_output_drive(pc, pin, arg);
381 break;
382 default:
230 default:
383 ret = -ENOTSUPP;
231 return -ENOTSUPP;
384 }
232 }
385
386 if (ret)
387 return ret;
388 }
389
390 return 0;
391}
392
393static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
394{
395 struct meson_bank *bank;

--- 23 unchanged lines hidden (view full) ---

419 conf = PIN_CONFIG_BIAS_PULL_UP;
420 else
421 conf = PIN_CONFIG_BIAS_PULL_DOWN;
422 }
423
424 return conf;
425}
426
233 }
234
235 return 0;
236}
237
238static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
239{
240 struct meson_bank *bank;

--- 23 unchanged lines hidden (view full) ---

264 conf = PIN_CONFIG_BIAS_PULL_UP;
265 else
266 conf = PIN_CONFIG_BIAS_PULL_DOWN;
267 }
268
269 return conf;
270}
271
427static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc,
428 unsigned int pin,
429 u16 *drive_strength_ua)
430{
431 struct meson_bank *bank;
432 unsigned int reg, bit;
433 unsigned int val;
434 int ret;
435
436 if (!pc->reg_ds)
437 return -ENOTSUPP;
438
439 ret = meson_get_bank(pc, pin, &bank);
440 if (ret)
441 return ret;
442
443 meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
444
445 ret = regmap_read(pc->reg_ds, reg, &val);
446 if (ret)
447 return ret;
448
449 switch ((val >> bit) & 0x3) {
450 case MESON_PINCONF_DRV_500UA:
451 *drive_strength_ua = 500;
452 break;
453 case MESON_PINCONF_DRV_2500UA:
454 *drive_strength_ua = 2500;
455 break;
456 case MESON_PINCONF_DRV_3000UA:
457 *drive_strength_ua = 3000;
458 break;
459 case MESON_PINCONF_DRV_4000UA:
460 *drive_strength_ua = 4000;
461 break;
462 default:
463 return -EINVAL;
464 }
465
466 return 0;
467}
468
469static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
470 unsigned long *config)
471{
472 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
473 enum pin_config_param param = pinconf_to_config_param(*config);
474 u16 arg;
272static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
273 unsigned long *config)
274{
275 struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
276 enum pin_config_param param = pinconf_to_config_param(*config);
277 u16 arg;
475 int ret;
476
477 switch (param) {
478 case PIN_CONFIG_BIAS_DISABLE:
479 case PIN_CONFIG_BIAS_PULL_DOWN:
480 case PIN_CONFIG_BIAS_PULL_UP:
481 if (meson_pinconf_get_pull(pc, pin) == param)
482 arg = 1;
483 else
484 return -EINVAL;
485 break;
278
279 switch (param) {
280 case PIN_CONFIG_BIAS_DISABLE:
281 case PIN_CONFIG_BIAS_PULL_DOWN:
282 case PIN_CONFIG_BIAS_PULL_UP:
283 if (meson_pinconf_get_pull(pc, pin) == param)
284 arg = 1;
285 else
286 return -EINVAL;
287 break;
486 case PIN_CONFIG_DRIVE_STRENGTH_UA:
487 ret = meson_pinconf_get_drive_strength(pc, pin, &arg);
488 if (ret)
489 return ret;
490 break;
491 case PIN_CONFIG_OUTPUT_ENABLE:
492 ret = meson_pinconf_get_output(pc, pin);
493 if (ret <= 0)
494 return -EINVAL;
495 arg = 1;
496 break;
497 case PIN_CONFIG_OUTPUT:
498 ret = meson_pinconf_get_output(pc, pin);
499 if (ret <= 0)
500 return -EINVAL;
501
502 ret = meson_pinconf_get_drive(pc, pin);
503 if (ret < 0)
504 return -EINVAL;
505
506 arg = ret;
507 break;
508
509 default:
510 return -ENOTSUPP;
511 }
512
513 *config = pinconf_to_config_packed(param, arg);
514 dev_dbg(pc->dev, "pinconf for pin %u is %lu\n", pin, *config);
515
516 return 0;

--- 28 unchanged lines hidden (view full) ---

545 .pin_config_set = meson_pinconf_set,
546 .pin_config_group_get = meson_pinconf_group_get,
547 .pin_config_group_set = meson_pinconf_group_set,
548 .is_generic = true,
549};
550
551static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
552{
288 default:
289 return -ENOTSUPP;
290 }
291
292 *config = pinconf_to_config_packed(param, arg);
293 dev_dbg(pc->dev, "pinconf for pin %u is %lu\n", pin, *config);
294
295 return 0;

--- 28 unchanged lines hidden (view full) ---

324 .pin_config_set = meson_pinconf_set,
325 .pin_config_group_get = meson_pinconf_group_get,
326 .pin_config_group_set = meson_pinconf_group_set,
327 .is_generic = true,
328};
329
330static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
331{
553 return meson_pinconf_set_output(gpiochip_get_data(chip), gpio, false);
332 struct meson_pinctrl *pc = gpiochip_get_data(chip);
333 unsigned int reg, bit;
334 struct meson_bank *bank;
335 int ret;
336
337 ret = meson_get_bank(pc, gpio, &bank);
338 if (ret)
339 return ret;
340
341 meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
342
343 return regmap_update_bits(pc->reg_gpio, reg, BIT(bit), BIT(bit));
554}
555
556static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
557 int value)
558{
344}
345
346static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
347 int value)
348{
559 return meson_pinconf_set_output_drive(gpiochip_get_data(chip),
560 gpio, value);
349 struct meson_pinctrl *pc = gpiochip_get_data(chip);
350 unsigned int reg, bit;
351 struct meson_bank *bank;
352 int ret;
353
354 ret = meson_get_bank(pc, gpio, &bank);
355 if (ret)
356 return ret;
357
358 meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
359 ret = regmap_update_bits(pc->reg_gpio, reg, BIT(bit), 0);
360 if (ret)
361 return ret;
362
363 meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
364 return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
365 value ? BIT(bit) : 0);
561}
562
563static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
564{
366}
367
368static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
369{
565 meson_pinconf_set_drive(gpiochip_get_data(chip), gpio, value);
370 struct meson_pinctrl *pc = gpiochip_get_data(chip);
371 unsigned int reg, bit;
372 struct meson_bank *bank;
373 int ret;
374
375 ret = meson_get_bank(pc, gpio, &bank);
376 if (ret)
377 return;
378
379 meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
380 regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
381 value ? BIT(bit) : 0);
566}
567
568static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
569{
570 struct meson_pinctrl *pc = gpiochip_get_data(chip);
571 unsigned int reg, bit, val;
572 struct meson_bank *bank;
573 int ret;

--- 156 unchanged lines hidden ---
382}
383
384static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
385{
386 struct meson_pinctrl *pc = gpiochip_get_data(chip);
387 unsigned int reg, bit, val;
388 struct meson_bank *bank;
389 int ret;

--- 156 unchanged lines hidden ---