|
@@ -878,14 +878,12 @@ static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
|
|
|
static int
|
|
|
sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
|
|
|
struct sdhci_host *host,
|
|
|
- struct esdhc_platform_data *boarddata)
|
|
|
+ struct pltfm_imx_data *imx_data)
|
|
|
{
|
|
|
struct device_node *np = pdev->dev.of_node;
|
|
|
+ struct esdhc_platform_data *boarddata = &imx_data->boarddata;
|
|
|
int ret;
|
|
|
|
|
|
- if (!np)
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
if (of_get_property(np, "non-removable", NULL))
|
|
|
boarddata->cd_type = ESDHC_CD_PERMANENT;
|
|
|
|
|
@@ -917,6 +915,26 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
|
|
|
|
|
|
mmc_of_parse_voltage(np, &host->ocr_mask);
|
|
|
|
|
|
+ /* sdr50 and sdr104 needs work on 1.8v signal voltage */
|
|
|
+ if ((boarddata->support_vsel) && esdhc_is_usdhc(imx_data) &&
|
|
|
+ !IS_ERR(imx_data->pins_default)) {
|
|
|
+ imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl,
|
|
|
+ ESDHC_PINCTRL_STATE_100MHZ);
|
|
|
+ imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl,
|
|
|
+ ESDHC_PINCTRL_STATE_200MHZ);
|
|
|
+ if (IS_ERR(imx_data->pins_100mhz) ||
|
|
|
+ IS_ERR(imx_data->pins_200mhz)) {
|
|
|
+ dev_warn(mmc_dev(host->mmc),
|
|
|
+ "could not get ultra high speed state, work on normal mode\n");
|
|
|
+ /*
|
|
|
+ * fall back to not support uhs by specify no 1.8v quirk
|
|
|
+ */
|
|
|
+ host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
|
|
|
+ }
|
|
|
+
|
|
|
/* call to generic mmc_of_parse to support additional capabilities */
|
|
|
ret = mmc_of_parse(host->mmc);
|
|
|
if (ret)
|
|
@@ -931,22 +949,85 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
|
|
|
static inline int
|
|
|
sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
|
|
|
struct sdhci_host *host,
|
|
|
- struct esdhc_platform_data *boarddata)
|
|
|
+ struct pltfm_imx_data *imx_data)
|
|
|
{
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+static int sdhci_esdhc_imx_probe_nondt(struct platform_device *pdev,
|
|
|
+ struct sdhci_host *host,
|
|
|
+ struct pltfm_imx_data *imx_data)
|
|
|
+{
|
|
|
+ struct esdhc_platform_data *boarddata = &imx_data->boarddata;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ if (!host->mmc->parent->platform_data) {
|
|
|
+ dev_err(mmc_dev(host->mmc), "no board data!\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ imx_data->boarddata = *((struct esdhc_platform_data *)
|
|
|
+ host->mmc->parent->platform_data);
|
|
|
+ /* write_protect */
|
|
|
+ if (boarddata->wp_type == ESDHC_WP_GPIO) {
|
|
|
+ err = mmc_gpio_request_ro(host->mmc, boarddata->wp_gpio);
|
|
|
+ if (err) {
|
|
|
+ dev_err(mmc_dev(host->mmc),
|
|
|
+ "failed to request write-protect gpio!\n");
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+ host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* card_detect */
|
|
|
+ switch (boarddata->cd_type) {
|
|
|
+ case ESDHC_CD_GPIO:
|
|
|
+ err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio, 0);
|
|
|
+ if (err) {
|
|
|
+ dev_err(mmc_dev(host->mmc),
|
|
|
+ "failed to request card-detect gpio!\n");
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+ /* fall through */
|
|
|
+
|
|
|
+ case ESDHC_CD_CONTROLLER:
|
|
|
+ /* we have a working card_detect back */
|
|
|
+ host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case ESDHC_CD_PERMANENT:
|
|
|
+ host->mmc->caps |= MMC_CAP_NONREMOVABLE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case ESDHC_CD_NONE:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (boarddata->max_bus_width) {
|
|
|
+ case 8:
|
|
|
+ host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA;
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ host->mmc->caps |= MMC_CAP_4_BIT_DATA;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ default:
|
|
|
+ host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
const struct of_device_id *of_id =
|
|
|
of_match_device(imx_esdhc_dt_ids, &pdev->dev);
|
|
|
struct sdhci_pltfm_host *pltfm_host;
|
|
|
struct sdhci_host *host;
|
|
|
- struct esdhc_platform_data *boarddata;
|
|
|
int err;
|
|
|
struct pltfm_imx_data *imx_data;
|
|
|
- bool dt = true;
|
|
|
|
|
|
host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0);
|
|
|
if (IS_ERR(host))
|
|
@@ -1038,84 +1119,12 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
|
|
|
if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
|
|
|
host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
|
|
|
|
|
|
- boarddata = &imx_data->boarddata;
|
|
|
- if (sdhci_esdhc_imx_probe_dt(pdev, host, boarddata) < 0) {
|
|
|
- if (!host->mmc->parent->platform_data) {
|
|
|
- dev_err(mmc_dev(host->mmc), "no board data!\n");
|
|
|
- err = -EINVAL;
|
|
|
- goto disable_clk;
|
|
|
- }
|
|
|
- imx_data->boarddata = *((struct esdhc_platform_data *)
|
|
|
- host->mmc->parent->platform_data);
|
|
|
- dt = false;
|
|
|
- }
|
|
|
- /* write_protect */
|
|
|
- if (boarddata->wp_type == ESDHC_WP_GPIO && !dt) {
|
|
|
- err = mmc_gpio_request_ro(host->mmc, boarddata->wp_gpio);
|
|
|
- if (err) {
|
|
|
- dev_err(mmc_dev(host->mmc),
|
|
|
- "failed to request write-protect gpio!\n");
|
|
|
- goto disable_clk;
|
|
|
- }
|
|
|
- host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
|
|
|
- }
|
|
|
-
|
|
|
- /* card_detect */
|
|
|
- switch (boarddata->cd_type) {
|
|
|
- case ESDHC_CD_GPIO:
|
|
|
- if (dt)
|
|
|
- break;
|
|
|
- err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio, 0);
|
|
|
- if (err) {
|
|
|
- dev_err(mmc_dev(host->mmc),
|
|
|
- "failed to request card-detect gpio!\n");
|
|
|
- goto disable_clk;
|
|
|
- }
|
|
|
- /* fall through */
|
|
|
-
|
|
|
- case ESDHC_CD_CONTROLLER:
|
|
|
- /* we have a working card_detect back */
|
|
|
- host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
|
|
|
- break;
|
|
|
-
|
|
|
- case ESDHC_CD_PERMANENT:
|
|
|
- host->mmc->caps |= MMC_CAP_NONREMOVABLE;
|
|
|
- break;
|
|
|
-
|
|
|
- case ESDHC_CD_NONE:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- switch (boarddata->max_bus_width) {
|
|
|
- case 8:
|
|
|
- host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA;
|
|
|
- break;
|
|
|
- case 4:
|
|
|
- host->mmc->caps |= MMC_CAP_4_BIT_DATA;
|
|
|
- break;
|
|
|
- case 1:
|
|
|
- default:
|
|
|
- host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- /* sdr50 and sdr104 needs work on 1.8v signal voltage */
|
|
|
- if ((boarddata->support_vsel) && esdhc_is_usdhc(imx_data) &&
|
|
|
- !IS_ERR(imx_data->pins_default)) {
|
|
|
- imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl,
|
|
|
- ESDHC_PINCTRL_STATE_100MHZ);
|
|
|
- imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl,
|
|
|
- ESDHC_PINCTRL_STATE_200MHZ);
|
|
|
- if (IS_ERR(imx_data->pins_100mhz) ||
|
|
|
- IS_ERR(imx_data->pins_200mhz)) {
|
|
|
- dev_warn(mmc_dev(host->mmc),
|
|
|
- "could not get ultra high speed state, work on normal mode\n");
|
|
|
- /* fall back to not support uhs by specify no 1.8v quirk */
|
|
|
- host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
|
|
|
- }
|
|
|
- } else {
|
|
|
- host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
|
|
|
- }
|
|
|
+ if (of_id)
|
|
|
+ err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
|
|
|
+ else
|
|
|
+ err = sdhci_esdhc_imx_probe_nondt(pdev, host, imx_data);
|
|
|
+ if (err)
|
|
|
+ goto disable_clk;
|
|
|
|
|
|
err = sdhci_add_host(host);
|
|
|
if (err)
|