Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1183484
  • 博文数量: 221
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2139
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(221)

文章存档

2024年(6)

2023年(8)

2022年(2)

2021年(2)

2020年(29)

2019年(11)

2018年(23)

2017年(41)

2016年(76)

2015年(23)

我的朋友
最近访客

分类: LINUX

2017-09-04 15:49:33

linux 4.10 s3c6410芯片USB(host,otg,gadget)的device板端


/* USB */

#ifdef CONFIG_S3C_DEV_USB_HOST
static struct resource s3c_usb_resource[] = {
//
//#define S3C_PA_USBHOST        S3C64XX_PA_USBHOST
//#define S3C64XX_PA_USBHOST    (0x74300000)
//HcRevision 0x74300000  R USB Host Controller Revision Register   这个地址是USB host寄存器组的第一个地址



    [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256),

//
//#define IRQ_USBH        S3C64XX_IRQ_VIC1(15)
    [1] = DEFINE_RES_IRQ(IRQ_USBH),
};

struct platform_device s3c_device_ohci = {
    .name        = "s3c2410-ohci",
    .id        = -1,
    .num_resources    = ARRAY_SIZE(s3c_usb_resource),
    .resource    = s3c_usb_resource,
    .dev        = {
        .dma_mask        = &samsung_device_dma_mask,
        .coherent_dma_mask    = DMA_BIT_MASK(32),
    }
};

/*
 * s3c_ohci_set_platdata - initialise OHCI device platform data
 * @info: The platform data.
 *
 * This call copies the @info passed in and sets the device .platform_data
 * field to that copy. The @info is copied so that the original can be marked
 * __initdata.
 */
static void __init bast_init(void)
---->>int __init usb_simtec_init(void)

void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
{
//申请内存,并复制数据usb_simtec_info到这个内存,将s3c_device_ohci->dev.platform_data指向这个内存
    s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
             &s3c_device_ohci);
}
#endif /* CONFIG_S3C_DEV_USB_HOST */


///////////////////////////////////////////////////////////////


/* USB Device (Gadget) */

#ifdef CONFIG_PLAT_S3C24XX
static struct resource s3c_usbgadget_resource[] = {
//arch/arm/mach-s3c24xx/include/mach/map.h
///* USB Device port */
//#define S3C2410_PA_USBDEV    (0x52000000)
//#define S3C24XX_SZ_USBDEV    SZ_1M
    [0] = DEFINE_RES_MEM(S3C24XX_PA_USBDEV, S3C24XX_SZ_USBDEV),

////arch/arm/mach-s3c24xx/include/mach/irqs.h
//#define IRQ_USBD       S3C2410_IRQ(25)
    [1] = DEFINE_RES_IRQ(IRQ_USBD),
};

struct platform_device s3c_device_usbgadget = {
    .name        = "s3c2410-usbgadget",
    .id        = -1,
    .num_resources    = ARRAY_SIZE(s3c_usbgadget_resource),
    .resource    = s3c_usbgadget_resource,
};

void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
{
    s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
}
#endif /* CONFIG_PLAT_S3C24XX */

////////////////////////////////////////////////////////////////////////////////////////////

/* USB HSOTG */

#ifdef CONFIG_S3C_DEV_USB_HSOTG
static struct resource s3c_usb_hsotg_resources[] = {
////
//#define S3C_PA_USB_HSOTG    S3C64XX_PA_USB_HSOTG
//#define S3C64XX_PA_USB_HSOTG    (0x7C000000)
    [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_128K),

//// //#define IRQ_OTG            S3C64XX_IRQ_VIC1(26)
    [1] = DEFINE_RES_IRQ(IRQ_OTG),
};

struct platform_device s3c_device_usb_hsotg = {
    .name        = "s3c-hsotg",
    .id        = -1,
    .num_resources    = ARRAY_SIZE(s3c_usb_hsotg_resources),
    .resource    = s3c_usb_hsotg_resources,
    .dev        = {
        .dma_mask        = &samsung_device_dma_mask,
        .coherent_dma_mask    = DMA_BIT_MASK(32),
    },
};
////
////static void __init smdk6410_machine_init(void)
//调用本函数dwc2_hsotg_set_platdata(&smdk6410_hsotg_pdata);
void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd)
{
    struct dwc2_hsotg_plat *npd;

    npd = s3c_set_platdata(pd, sizeof(struct dwc2_hsotg_plat),
            &s3c_device_usb_hsotg);

    if (!npd->phy_init)
        npd->phy_init = s5p_usb_phy_init;
    if (!npd->phy_exit)
        npd->phy_exit = s5p_usb_phy_exit;
}
#endif /* CONFIG_S3C_DEV_USB_HSOTG */

/* USB High Spped 2.0 Device (Gadget) */

#ifdef CONFIG_PLAT_S3C24XX
static struct resource s3c_hsudc_resource[] = {
    [0] = DEFINE_RES_MEM(S3C2416_PA_HSUDC, S3C2416_SZ_HSUDC),
    [1] = DEFINE_RES_IRQ(IRQ_USBD),
};

struct platform_device s3c_device_usb_hsudc = {
    .name        = "s3c-hsudc",
    .id        = -1,
    .num_resources    = ARRAY_SIZE(s3c_hsudc_resource),
    .resource    = s3c_hsudc_resource,
    .dev        = {
        .dma_mask        = &samsung_device_dma_mask,
        .coherent_dma_mask    = DMA_BIT_MASK(32),
    },
};

void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
{
    s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
}
#endif /* CONFIG_PLAT_S3C24XX */

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int s5p_usb_phy_init(struct platform_device *pdev, int type)
{
    if (type == USB_PHY_TYPE_DEVICE)
        return s3c_usb_otgphy_init(pdev);

    return -EINVAL;
}
static int s3c_usb_otgphy_init(struct platform_device *pdev)
{
    struct clk *xusbxti;
    u32 phyclk;

    writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);

    /* set clock frequency for PLL */
    phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;

    xusbxti = clk_get(&pdev->dev, "xusbxti");
    if (xusbxti && !IS_ERR(xusbxti)) {
        switch (clk_get_rate(xusbxti)) {
        case 12 * MHZ:
            phyclk |= S3C_PHYCLK_CLKSEL_12M;
            break;
        case 24 * MHZ:
            phyclk |= S3C_PHYCLK_CLKSEL_24M;
            break;
        default:
        case 48 * MHZ:
            /* default reference clock */
            break;
        }
        clk_put(xusbxti);
    }

    /* TODO: select external clock/oscillator */
    writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);

    /* set to normal OTG PHY */
    writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
    mdelay(1);

    /* reset OTG PHY and Link */
    writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
            S3C_RSTCON);
    udelay(20);    /* at-least 10uS */
    writel(0, S3C_RSTCON);

    return 0;
}

////////////////////////////////////////////////////////////////////////////////

static void __init bast_init(void) ----->usb_simtec_init();


int __init usb_simtec_init(void)
{
    int ret;

    printk("USB Power Control, Copyright 2004 Simtec Electronics\n");

    ret = gpio_request(S3C2410_GPB(4), "USB power control");
    if (ret < 0) {
        pr_err("%s: failed to get GPB4\n", __func__);
        return ret;
    }

    ret = gpio_request(S3C2410_GPG(10), "USB overcurrent");
    if (ret < 0) {
        pr_err("%s: failed to get GPG10\n", __func__);
        gpio_free(S3C2410_GPB(4));
        return ret;
    }

    /* turn power on */
    gpio_direction_output(S3C2410_GPB(4), 1);
    gpio_direction_input(S3C2410_GPG(10));

    s3c_ohci_set_platdata(&usb_simtec_info);
    return 0;
}
///////////






阅读(979) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~