/* 
 | 
 * Support of SDHCI for Microchip PIC32 SoC. 
 | 
 * 
 | 
 * Copyright (C) 2015 Microchip Technology Inc. 
 | 
 * Andrei Pistirica <andrei.pistirica@microchip.com> 
 | 
 * 
 | 
 * SPDX-License-Identifier:    GPL-2.0+ 
 | 
 */ 
 | 
  
 | 
#include <common.h> 
 | 
#include <dm.h> 
 | 
#include <sdhci.h> 
 | 
#include <linux/errno.h> 
 | 
#include <mach/pic32.h> 
 | 
  
 | 
DECLARE_GLOBAL_DATA_PTR; 
 | 
  
 | 
static int pic32_sdhci_get_cd(struct sdhci_host *host) 
 | 
{ 
 | 
    /* PIC32 SDHCI CD errata: 
 | 
     * - set CD_TEST and clear CD_TEST_INS bit 
 | 
     */ 
 | 
    sdhci_writeb(host, SDHCI_CTRL_CD_TEST, SDHCI_HOST_CONTROL); 
 | 
  
 | 
    return 0; 
 | 
} 
 | 
  
 | 
static const struct sdhci_ops pic32_sdhci_ops = { 
 | 
    .get_cd    = pic32_sdhci_get_cd, 
 | 
}; 
 | 
  
 | 
static int pic32_sdhci_probe(struct udevice *dev) 
 | 
{ 
 | 
    struct sdhci_host *host = dev_get_priv(dev); 
 | 
    const void *fdt = gd->fdt_blob; 
 | 
    u32 f_min_max[2]; 
 | 
    fdt_addr_t addr; 
 | 
    fdt_size_t size; 
 | 
    int ret; 
 | 
  
 | 
    addr = fdtdec_get_addr_size(fdt, dev_of_offset(dev), "reg", &size); 
 | 
    if (addr == FDT_ADDR_T_NONE) 
 | 
        return -EINVAL; 
 | 
  
 | 
    host->ioaddr    = ioremap(addr, size); 
 | 
    host->name    = dev->name; 
 | 
    host->quirks    = SDHCI_QUIRK_NO_HISPD_BIT; 
 | 
    host->bus_width    = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), 
 | 
                    "bus-width", 4); 
 | 
    host->ops = &pic32_sdhci_ops; 
 | 
  
 | 
    ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), 
 | 
                   "clock-freq-min-max", f_min_max, 2); 
 | 
    if (ret) { 
 | 
        printf("sdhci: clock-freq-min-max not found\n"); 
 | 
        return ret; 
 | 
    } 
 | 
  
 | 
    host->max_clk   = f_min_max[1]; 
 | 
  
 | 
    ret = add_sdhci(host, 0, f_min_max[0]); 
 | 
    if (ret) 
 | 
        return ret; 
 | 
    host->mmc->dev = dev; 
 | 
  
 | 
    return 0; 
 | 
} 
 | 
  
 | 
static const struct udevice_id pic32_sdhci_ids[] = { 
 | 
    { .compatible = "microchip,pic32mzda-sdhci" }, 
 | 
    { } 
 | 
}; 
 | 
  
 | 
U_BOOT_DRIVER(pic32_sdhci_drv) = { 
 | 
    .name            = "pic32_sdhci", 
 | 
    .id            = UCLASS_MMC, 
 | 
    .of_match        = pic32_sdhci_ids, 
 | 
    .probe            = pic32_sdhci_probe, 
 | 
    .priv_auto_alloc_size    = sizeof(struct sdhci_host), 
 | 
}; 
 |