@@ -72,17 +72,33 @@
/* Custom pinconf parameters */
#define ATMEL_PIN_CONFIG_DRIVE_STRENGTH (PIN_CONFIG_END + 1)
+static const unsigned int drive_strength_xlate_sama7g5[] = {
+ ATMEL_PIO_DRVSTR_LO_D,
+ ATMEL_PIO_DRVSTR_HI_A,
+ ATMEL_PIO_DRVSTR_LO_C,
+ ATMEL_PIO_DRVSTR_LO_B
+};
+
+static const unsigned int drive_strength_xlate_sama5d2[] = {
+ ATMEL_PIO_DRVSTR_LO,
+ ATMEL_PIO_DRVSTR_LO_1,
+ ATMEL_PIO_DRVSTR_ME,
+ ATMEL_PIO_DRVSTR_HI
+};
+
/**
* struct atmel_pioctrl_data - Atmel PIO controller (pinmux + gpio) data struct
* @nbanks: number of PIO banks
* @last_bank_count: number of lines in the last bank (can be less than
* the rest of the banks).
* @slew_rate_support: slew rate support
+ * @drv_stre_xlate: xlate for different drive values
*/
struct atmel_pioctrl_data {
unsigned int nbanks;
unsigned int last_bank_count;
unsigned int slew_rate_support;
+ const unsigned int *drv_stre_xlate;
};
struct atmel_group {
@@ -121,6 +137,7 @@ struct atmel_pin {
* @dev: device entry for the Atmel PIO controller.
* @node: node of the Atmel PIO controller.
* @slew_rate_support: slew rate support
+ * @drv_stre_xlate: xlate for different drive values
*/
struct atmel_pioctrl {
void __iomem *reg_base;
@@ -143,6 +160,7 @@ struct atmel_pioctrl {
struct device *dev;
struct device_node *node;
unsigned int slew_rate_support;
+ const unsigned int *drv_stre_xlate;
};
static const char * const atmel_functions[] = {
@@ -872,12 +890,17 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev,
conf &= ~ATMEL_PIO_SR_MASK;
break;
case ATMEL_PIN_CONFIG_DRIVE_STRENGTH:
+ if (arg > ATMEL_PIO_DRVSTR_HI || arg < ATMEL_PIO_DRVSTR_LO) {
+ dev_warn(pctldev->dev, "drive strength not updated (incorrect value)\n");
+ break;
+ }
switch (arg) {
case ATMEL_PIO_DRVSTR_LO:
+ case ATMEL_PIO_DRVSTR_LO_1:
case ATMEL_PIO_DRVSTR_ME:
case ATMEL_PIO_DRVSTR_HI:
conf &= (~ATMEL_PIO_DRVSTR_MASK);
- conf |= arg << ATMEL_PIO_DRVSTR_OFFSET;
+ conf |= atmel_pioctrl->drv_stre_xlate[arg] << ATMEL_PIO_DRVSTR_OFFSET;
break;
default:
dev_warn(pctldev->dev, "drive strength not updated (incorrect value)\n");
@@ -903,6 +926,8 @@ static void atmel_conf_pin_config_dbg_show(struct pinctrl_dev *pctldev,
{
struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
u32 conf;
+ unsigned int arg;
+ u8 is_sama7 = atmel_pioctrl->drv_stre_xlate == drive_strength_xlate_sama7g5;
if (!atmel_pioctrl->pins[pin_id]->device)
return;
@@ -926,16 +951,32 @@ static void atmel_conf_pin_config_dbg_show(struct pinctrl_dev *pctldev,
if (atmel_pioctrl->slew_rate_support && (conf & ATMEL_PIO_SR_MASK))
seq_printf(s, "%s ", "slew-rate");
if (conf & ATMEL_PIO_DRVSTR_MASK) {
- switch ((conf & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET) {
+ arg = (conf & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET;
+ switch (atmel_pioctrl->drv_stre_xlate[arg]) {
case ATMEL_PIO_DRVSTR_ME:
- seq_printf(s, "%s ", "medium-drive");
+ if (is_sama7)
+ seq_printf(s, "%s ", "low-drive-typeD");
+ else
+ seq_printf(s, "%s ", "medium-drive");
break;
case ATMEL_PIO_DRVSTR_HI:
- seq_printf(s, "%s ", "high-drive");
+ if (is_sama7)
+ seq_printf(s, "%s ", "low-drive-typeB");
+ else
+ seq_printf(s, "%s ", "high-drive");
+ break;
+ case ATMEL_PIO_DRVSTR_HI_A:
+ if (is_sama7)
+ seq_printf(s, "%s ", "high-drive-typeA");
+ else
+ seq_printf(s, "%s ", "low-drive");
break;
/* ATMEL_PIO_DRVSTR_LO and 0 which is the default value at reset */
default:
- seq_printf(s, "%s ", "low-drive");
+ if (is_sama7)
+ seq_printf(s, "%s ", "low-drive-typeD");
+ else
+ seq_printf(s, "%s ", "low-drive");
}
}
}
@@ -1013,12 +1054,14 @@ static const struct dev_pm_ops atmel_pctrl_pm_ops = {
static const struct atmel_pioctrl_data atmel_sama5d2_pioctrl_data = {
.nbanks = 4,
.last_bank_count = ATMEL_PIO_NPINS_PER_BANK,
+ .drv_stre_xlate = drive_strength_xlate_sama5d2,
};
static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = {
.nbanks = 5,
.last_bank_count = 8, /* sama7g5 has only PE0 to PE7 */
.slew_rate_support = 1,
+ .drv_stre_xlate = drive_strength_xlate_sama7g5,
};
static const struct of_device_id atmel_pctrl_of_match[] = {
@@ -1064,6 +1107,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
atmel_pioctrl->npins += atmel_pioctrl_data->last_bank_count;
}
atmel_pioctrl->slew_rate_support = atmel_pioctrl_data->slew_rate_support;
+ atmel_pioctrl->drv_stre_xlate = atmel_pioctrl_data->drv_stre_xlate;
atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(atmel_pioctrl->reg_base))