u32 power_off_delay_us;
struct clk *ext_clk;
struct gpio_descs *reset_gpios;
+ struct gpio_descs *chip_en_gpios;
};
#define to_pwrseq_simple(p) container_of(p, struct mmc_pwrseq_simple, pwrseq)
int value)
{
struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
+ struct gpio_descs *chip_en_gpios = pwrseq->chip_en_gpios;
if (!IS_ERR(reset_gpios)) {
int i, *values;
for (i = 0; i < nvalues; i++)
values[i] = value;
- gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc, values);
+ if (!IS_ERR(reset_gpios) && !IS_ERR(chip_en_gpios)) {
+ int *values_chip_en;
+ int nvalues_chip_en = chip_en_gpios->ndescs;
+ values_chip_en = kmalloc_array(nvalues_chip_en, sizeof(int), GFP_KERNEL);
+ if (!values_chip_en) {
+ kfree(values);
+ return;
+ }
+ for (i = 0; i < nvalues_chip_en; i++)
+ values_chip_en[i] = value;
+
+ if (!value) {
+ //Power on sequence
+ gpiod_set_array_value_cansleep(
+ nvalues_chip_en, chip_en_gpios->desc, values_chip_en);
+ msleep(5);
+ gpiod_set_array_value_cansleep(
+ nvalues, reset_gpios->desc, values);
+ } else {
+ //Power off sequence
+ gpiod_set_array_value_cansleep(
+ nvalues, reset_gpios->desc, values);
+ msleep(5);
+ gpiod_set_array_value_cansleep(
+ nvalues_chip_en, chip_en_gpios->desc, values_chip_en);
+ }
+ kfree(values_chip_en);
+ } else {
+ gpiod_set_array_value_cansleep(
+ nvalues, reset_gpios->desc, values);
+ }
kfree(values);
}
}
return PTR_ERR(pwrseq->reset_gpios);
}
+ pwrseq->chip_en_gpios = devm_gpiod_get_array(dev, "chip_en",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(pwrseq->chip_en_gpios) &&
+ PTR_ERR(pwrseq->chip_en_gpios) != -ENOENT &&
+ PTR_ERR(pwrseq->chip_en_gpios) != -ENOSYS) {
+ return PTR_ERR(pwrseq->chip_en_gpios);
+ }
+
device_property_read_u32(dev, "post-power-on-delay-ms",
&pwrseq->post_power_on_delay_ms);
device_property_read_u32(dev, "power-off-delay-us",