[AVR32] Implement at32_add_device_cf()
Implement at32_add_device_cf() which will add a platform_device for the at32_cf driver (not merged yet). Separate out most of the at32_add_device_ide() code and use it to implement at32_add_device_cf() as well. This changes the API in the following ways: * The board code must initialize data->cs to the chipselect ID to use before calling any of these functions. * The board code must use GPIO_PIN_NONE to indicate unused CF pins. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>hifive-unleashed-5.1
parent
2042c1c4e7
commit
eaf5f925a3
|
@ -1330,10 +1330,9 @@ out_free_pdev:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------
|
/* --------------------------------------------------------------------
|
||||||
* IDE
|
* IDE / CompactFlash
|
||||||
* -------------------------------------------------------------------- */
|
* -------------------------------------------------------------------- */
|
||||||
static struct ide_platform_data at32_ide0_data;
|
static struct resource at32_smc_cs4_resource[] __initdata = {
|
||||||
static struct resource at32_ide0_resource[] = {
|
|
||||||
{
|
{
|
||||||
.start = 0x04000000,
|
.start = 0x04000000,
|
||||||
.end = 0x07ffffff,
|
.end = 0x07ffffff,
|
||||||
|
@ -1341,45 +1340,63 @@ static struct resource at32_ide0_resource[] = {
|
||||||
},
|
},
|
||||||
IRQ(~0UL), /* Magic IRQ will be overridden */
|
IRQ(~0UL), /* Magic IRQ will be overridden */
|
||||||
};
|
};
|
||||||
DEFINE_DEV_DATA(at32_ide, 0);
|
static struct resource at32_smc_cs5_resource[] __initdata = {
|
||||||
|
{
|
||||||
|
.start = 0x20000000,
|
||||||
|
.end = 0x23ffffff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
IRQ(~0UL), /* Magic IRQ will be overridden */
|
||||||
|
};
|
||||||
|
|
||||||
struct platform_device *__init
|
static int __init at32_init_ide_or_cf(struct platform_device *pdev,
|
||||||
at32_add_device_ide(unsigned int id, unsigned int extint,
|
unsigned int cs, unsigned int extint)
|
||||||
struct ide_platform_data *data)
|
|
||||||
{
|
{
|
||||||
struct platform_device *pdev;
|
static unsigned int extint_pin_map[4] __initdata = {
|
||||||
|
GPIO_PIN_PB(25),
|
||||||
|
GPIO_PIN_PB(26),
|
||||||
|
GPIO_PIN_PB(27),
|
||||||
|
GPIO_PIN_PB(28),
|
||||||
|
};
|
||||||
|
static bool common_pins_initialized __initdata = false;
|
||||||
unsigned int extint_pin;
|
unsigned int extint_pin;
|
||||||
|
int ret;
|
||||||
|
|
||||||
switch (extint) {
|
if (extint >= ARRAY_SIZE(extint_pin_map))
|
||||||
case 0:
|
return -EINVAL;
|
||||||
extint_pin = GPIO_PIN_PB(25);
|
extint_pin = extint_pin_map[extint];
|
||||||
|
|
||||||
|
switch (cs) {
|
||||||
|
case 4:
|
||||||
|
ret = platform_device_add_resources(pdev,
|
||||||
|
at32_smc_cs4_resource,
|
||||||
|
ARRAY_SIZE(at32_smc_cs4_resource));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
select_peripheral(PE(21), PERIPH_A, 0); /* NCS4 -> OE_N */
|
||||||
|
set_ebi_sfr_bits(HMATRIX_BIT(CS4A));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 5:
|
||||||
extint_pin = GPIO_PIN_PB(26);
|
ret = platform_device_add_resources(pdev,
|
||||||
break;
|
at32_smc_cs5_resource,
|
||||||
case 2:
|
ARRAY_SIZE(at32_smc_cs5_resource));
|
||||||
extint_pin = GPIO_PIN_PB(27);
|
if (ret)
|
||||||
break;
|
return ret;
|
||||||
case 3:
|
|
||||||
extint_pin = GPIO_PIN_PB(28);
|
select_peripheral(PE(22), PERIPH_A, 0); /* NCS5 -> OE_N */
|
||||||
|
set_ebi_sfr_bits(HMATRIX_BIT(CS5A));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (id) {
|
if (!common_pins_initialized) {
|
||||||
case 0:
|
|
||||||
pdev = &at32_ide0_device;
|
|
||||||
select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1 -> CS0_N */
|
select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1 -> CS0_N */
|
||||||
select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2 -> CS1_N */
|
select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2 -> CS1_N */
|
||||||
select_peripheral(PE(21), PERIPH_A, 0); /* NCS4 -> OE_N */
|
|
||||||
select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW -> DIR */
|
select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW -> DIR */
|
||||||
select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT <- IORDY */
|
select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT <- IORDY */
|
||||||
set_ebi_sfr_bits(HMATRIX_BIT(CS4A));
|
common_pins_initialized = true;
|
||||||
data->cs = 4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH);
|
at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH);
|
||||||
|
@ -1387,11 +1404,65 @@ at32_add_device_ide(unsigned int id, unsigned int extint,
|
||||||
pdev->resource[1].start = EIM_IRQ_BASE + extint;
|
pdev->resource[1].start = EIM_IRQ_BASE + extint;
|
||||||
pdev->resource[1].end = pdev->resource[1].start;
|
pdev->resource[1].end = pdev->resource[1].start;
|
||||||
|
|
||||||
memcpy(pdev->dev.platform_data, data, sizeof(struct ide_platform_data));
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
platform_device_register(pdev);
|
struct platform_device *__init
|
||||||
|
at32_add_device_ide(unsigned int id, unsigned int extint,
|
||||||
|
struct ide_platform_data *data)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev;
|
||||||
|
|
||||||
|
pdev = platform_device_alloc("at32_ide", id);
|
||||||
|
if (!pdev)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (platform_device_add_data(pdev, data,
|
||||||
|
sizeof(struct ide_platform_data)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (at32_init_ide_or_cf(pdev, data->cs, extint))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
platform_device_add(pdev);
|
||||||
return pdev;
|
return pdev;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
platform_device_put(pdev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct platform_device *__init
|
||||||
|
at32_add_device_cf(unsigned int id, unsigned int extint,
|
||||||
|
struct cf_platform_data *data)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev;
|
||||||
|
|
||||||
|
pdev = platform_device_alloc("at32_cf", id);
|
||||||
|
if (!pdev)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (platform_device_add_data(pdev, data,
|
||||||
|
sizeof(struct cf_platform_data)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (at32_init_ide_or_cf(pdev, data->cs, extint))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (data->detect_pin != GPIO_PIN_NONE)
|
||||||
|
at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH);
|
||||||
|
if (data->reset_pin != GPIO_PIN_NONE)
|
||||||
|
at32_select_gpio(data->reset_pin, 0);
|
||||||
|
if (data->vcc_pin != GPIO_PIN_NONE)
|
||||||
|
at32_select_gpio(data->vcc_pin, 0);
|
||||||
|
/* READY is used as extint, so we can't select it as gpio */
|
||||||
|
|
||||||
|
platform_device_add(pdev);
|
||||||
|
return pdev;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
platform_device_put(pdev);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------
|
/* --------------------------------------------------------------------
|
||||||
|
|
|
@ -70,4 +70,15 @@ struct platform_device *at32_add_device_mci(unsigned int id);
|
||||||
struct platform_device *at32_add_device_ac97c(unsigned int id);
|
struct platform_device *at32_add_device_ac97c(unsigned int id);
|
||||||
struct platform_device *at32_add_device_abdac(unsigned int id);
|
struct platform_device *at32_add_device_abdac(unsigned int id);
|
||||||
|
|
||||||
|
struct cf_platform_data {
|
||||||
|
int detect_pin;
|
||||||
|
int reset_pin;
|
||||||
|
int vcc_pin;
|
||||||
|
int ready_pin;
|
||||||
|
u8 cs;
|
||||||
|
};
|
||||||
|
struct platform_device *
|
||||||
|
at32_add_device_cf(unsigned int id, unsigned int extint,
|
||||||
|
struct cf_platform_data *data);
|
||||||
|
|
||||||
#endif /* __ASM_ARCH_BOARD_H */
|
#endif /* __ASM_ARCH_BOARD_H */
|
||||||
|
|
Loading…
Reference in New Issue