Skip to content

Commit

Permalink
N9: Init SSI driver
Browse files Browse the repository at this point in the history
Configure, load HSI controller module
during platform startup.

Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
  • Loading branch information
dziedjan authored and Kalle Jokiniemi committed Mar 18, 2013
1 parent e3c9a56 commit 5aca0f0
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 2 deletions.
3 changes: 3 additions & 0 deletions arch/arm/mach-omap2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ endif
# OMAP2420 MSDI controller integration support ("MMC")
obj-$(CONFIG_SOC_OMAP2420) += msdi.o

omap-ssi-$(CONFIG_OMAP_SSI) := ssi.o
obj-y += $(omap-ssi-m) $(omap-ssi-y)

# DSS
omap-dss-$(CONFIG_OMAP2_DSS) := dss.o
obj-y += $(omap-dss-m) $(omap-dss-y)
Expand Down
30 changes: 30 additions & 0 deletions arch/arm/mach-omap2/board-rm680.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/spi/spi.h>
#include <linux/cpu.h>
#include <linux/opp.h>
#include <linux/hsi/hsi.h>

#include <asm/mach/arch.h>
#include <asm/mach-types.h>
Expand All @@ -45,6 +46,7 @@
#include <linux/pvr.h>
#include <plat/mcspi.h>
#include <plat/omap_device.h>
#include <plat/ssi.h>

#include "mux.h"
#include "hsmmc.h"
Expand All @@ -58,6 +60,33 @@
#define ATMEL_MXT_IRQ_GPIO 61
#define ATMEL_MXT_RESET_GPIO 81

/* SSI init data */
static struct omap_ssi_port_config __initdata rm696_ssi_port_config[] = {
[0] = {
.cawake_gpio = 151,
.ready_rx_gpio = 154,
},
};

static struct omap_ssi_board_config __initdata rm696_ssi_config = {
.num_ports = ARRAY_SIZE(rm696_ssi_port_config),
.port_config = rm696_ssi_port_config,
};

static struct hsi_board_info __initdata rm696_ssi_cl[] = {
[0] = {
.name = "hsi_char",
.hsi_id = 0,
.port = 0,
},
};

static void __init rm696_ssi_init(void)
{
omap_ssi_config(&rm696_ssi_config);
hsi_register_board_info(rm696_ssi_cl, ARRAY_SIZE(rm696_ssi_cl));
}

/* CPU table initialization */
static int __init rm696_opp_init(void)
{
Expand Down Expand Up @@ -672,6 +701,7 @@ static void __init rm680_peripherals_init(void)
rm680_i2c_init();
gpmc_onenand_init(board_onenand_data);
omap_hsmmc_init(mmc);
rm696_ssi_init();
omap_bt_init(&rm680_bt_config);
}

Expand Down
156 changes: 156 additions & 0 deletions arch/arm/mach-omap2/ssi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* linux/arch/arm/mach-omap2/ssi.c
*
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
*
* Contact: Carlos Chinea <carlos.chinea@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <plat/omap-pm.h>
#include <plat/ssi.h>

/* FIXME: Pad offset maybe should be somewhere else*/
static struct omap_ssi_port_pdata ssi_port_pdata[] = {
[0] = {
.ready_rx_pad = 0x188,
.ready_tx_pad = 0x180,
},
};

static struct omap_ssi_platform_data ssi_pdata = {
.num_ports = ARRAY_SIZE(ssi_port_pdata),
.get_dev_context_loss_count = omap_pm_get_dev_context_loss_count,
.port_data = ssi_port_pdata,
};

static struct resource ssi_resources[] = {
/* SSI controller */
[0] = {
.start = 0x48058000,
.end = 0x48058fff,
.name = "omap_ssi_sys",
.flags = IORESOURCE_MEM,
},
/* GDD */
[1] = {
.start = 0x48059000,
.end = 0x48059fff,
.name = "omap_ssi_gdd",
.flags = IORESOURCE_MEM,
},
[2] = {
.start = 71,
.end = 71,
.name = "ssi_gdd",
.flags = IORESOURCE_IRQ,
},
/* SSI port 1 */
[3] = {
.start = 0x4805a000,
.end = 0x4805a7ff,
.name = "omap_ssi_sst1",
.flags = IORESOURCE_MEM,
},
[4] = {
.start = 0x4805a800,
.end = 0x4805afff,
.name = "omap_ssi_ssr1",
.flags = IORESOURCE_MEM,
},
[5] = {
.start = 67,
.end = 67,
.name = "ssi_p1_mpu_irq0",
.flags = IORESOURCE_IRQ,
},
[6] = {
.start = 68,
.end = 68,
.name = "ssi_p1_mpu_irq1",
.flags = IORESOURCE_IRQ,
},
[7] = {
.start = 0,
.end = 0,
.name = "ssi_p1_cawake",
.flags = IORESOURCE_IRQ | IORESOURCE_UNSET,
},
};

static struct platform_device ssi_pdev = {
.name = "omap_ssi",
.id = 0,
.num_resources = ARRAY_SIZE(ssi_resources),
.resource = ssi_resources,
.dev = {
.platform_data = &ssi_pdata,
},
};

int __init omap_ssi_config(struct omap_ssi_board_config *ssi_config)
{
unsigned int port, offset, cawake_gpio, ready_rx_gpio;
int err;

ssi_pdata.num_ports = ssi_config->num_ports;
for (port = 0, offset = 7; port < ssi_config->num_ports;
port++, offset += 5) {
cawake_gpio = ssi_config->port_config[port].cawake_gpio;
if (!cawake_gpio)
continue; /* Nothing to do */
err = gpio_request(cawake_gpio, "cawake");
if (err < 0) {
dev_err(&ssi_pdev.dev, "Request cawake (gpio%d)"
" failed\n", cawake_gpio);
goto rback;
}
gpio_direction_input(cawake_gpio);
ssi_resources[offset].start = gpio_to_irq(cawake_gpio);
ssi_resources[offset].flags &= ~IORESOURCE_UNSET;
ssi_resources[offset].flags |= IORESOURCE_IRQ_HIGHEDGE |
IORESOURCE_IRQ_LOWEDGE;
/* DVFS workaround */
ready_rx_gpio = ssi_config->port_config[port].ready_rx_gpio;
err = gpio_request(ready_rx_gpio, "ssi_ready_rx");
if (err < 0) {
dev_err(&ssi_pdev.dev, "Request ssi_ready_rx gpio%d"
" failed\n", ready_rx_gpio);
gpio_free(cawake_gpio);
goto rback;
}
gpio_direction_output(ready_rx_gpio, 0);
}

return 0;
rback:
while (port-- > 0) {
gpio_free(ssi_config->port_config[port].cawake_gpio);
gpio_free(ssi_config->port_config[port].ready_rx_gpio);
}
return err;
}

static int __init ssi_init(void)
{
return platform_device_register(&ssi_pdev);
}
subsys_initcall(ssi_init);
3 changes: 1 addition & 2 deletions drivers/gpio/gpio-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,10 @@ struct gpio_bank {
#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
#define GPIO_MOD_CTRL_BIT BIT(0)

int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq)
static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq)
{
return gpio_irq - bank->irq_base + bank->chip.base;
}
EXPORT_SYMBOL(irq_to_gpio);

static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
{
Expand Down
11 changes: 11 additions & 0 deletions drivers/hsi/controllers/omap_ssi.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@
#define SSI_MAX_GDD_LCH 8
#define SSI_BYTES_TO_FRAMES(x) ((((x) - 1) >> 2) + 1)

static inline int irq_to_gpio(unsigned irq)
{
int tmp;

tmp = irq - IH_GPIO_BASE;
if (tmp < OMAP_MAX_GPIO_LINES)
return tmp;

return -EIO;
}

/**
* struct ssi_clk_res - Device resource data for the SSI clocks
* @clk: Pointer to the clock
Expand Down

0 comments on commit 5aca0f0

Please sign in to comment.