diff options
author | Kamil Debski <k.debski@samsung.com> | 2013-05-22 16:26:37 +0200 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-11-18 11:43:21 +0900 |
commit | 55ccb02b22db012b1066a1a29a475e99a381ae47 (patch) | |
tree | 64439f80d3e4c93f848835b17a5754bd3999af3c /drivers | |
parent | 4dc4c75f6f5b324942b4efee9f33438f106a9beb (diff) | |
download | linux-3.10-55ccb02b22db012b1066a1a29a475e99a381ae47.tar.gz linux-3.10-55ccb02b22db012b1066a1a29a475e99a381ae47.tar.bz2 linux-3.10-55ccb02b22db012b1066a1a29a475e99a381ae47.zip |
modem_if: Move code from board-m0-modems.c to the modem driver
Move modem related code from the board file to the modem driver.
Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/misc/modem_if/sipc4_modem.c | 241 |
1 files changed, 239 insertions, 2 deletions
diff --git a/drivers/misc/modem_if/sipc4_modem.c b/drivers/misc/modem_if/sipc4_modem.c index 65d944436cc..30560e05d26 100644 --- a/drivers/misc/modem_if/sipc4_modem.c +++ b/drivers/misc/modem_if/sipc4_modem.c @@ -34,6 +34,8 @@ #include <linux/wakelock.h> #endif #include <linux/rbtree.h> +#include <linux/of.h> +#include <linux/of_gpio.h> #include <linux/platform_data/modem.h> #include "modem_prj.h" @@ -44,6 +46,100 @@ #define RFS_WAKE_TIME (HZ*3) #define RAW_WAKE_TIME (HZ*6) + +/* umts target platform data */ +static struct modem_io_t umts_io_devices[] = { + [0] = { + .name = "umts_ipc0", + .id = 0x1, + .format = IPC_FMT, + .io_type = IODEV_MISC, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [1] = { + .name = "umts_rfs0", + .id = 0x41, + .format = IPC_RFS, + .io_type = IODEV_MISC, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [2] = { + .name = "umts_boot0", + .id = 0x0, + .format = IPC_BOOT, + .io_type = IODEV_MISC, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [3] = { + .name = "multipdp", + .id = 0x1, + .format = IPC_MULTI_RAW, + .io_type = IODEV_DUMMY, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [4] = { +#ifdef CONFIG_SLP + .name = "pdp0", +#else + .name = "rmnet0", +#endif + .id = 0x2A, + .format = IPC_RAW, + .io_type = IODEV_NET, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [5] = { +#ifdef CONFIG_SLP + .name = "pdp1", +#else + .name = "rmnet1", +#endif + .id = 0x2B, + .format = IPC_RAW, + .io_type = IODEV_NET, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [6] = { +#ifdef CONFIG_SLP + .name = "pdp2", +#else + .name = "rmnet2", +#endif + .id = 0x2C, + .format = IPC_RAW, + .io_type = IODEV_NET, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [7] = { + .name = "umts_router", + .id = 0x39, + .format = IPC_RAW, + .io_type = IODEV_MISC, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [8] = { + .name = "umts_csd", + .id = 0x21, + .format = IPC_RAW, + .io_type = IODEV_MISC, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [9] = { + .name = "umts_ramdump0", + .id = 0x0, + .format = IPC_RAMDUMP, + .io_type = IODEV_MISC, + .links = LINKTYPE(LINKDEV_HSIC), + }, + [10] = { + .name = "umts_loopback0", + .id = 0x3f, + .format = IPC_RAW, + .io_type = IODEV_MISC, + .links = LINKTYPE(LINKDEV_HSIC), + }, +}; + static struct modem_shared *create_modem_shared_data(void) { struct modem_shared *msd; @@ -243,13 +339,131 @@ static int attach_devices(struct io_device *iod, enum modem_link tx_link) return 0; } +static struct modem_data *modem_parse_dt(struct platform_device *pdev, struct device_node *np) +{ + struct modem_data *mc; + int err = 0; + + mc = kzalloc(sizeof(struct modem_data), GFP_KERNEL); + if (!mc) { + mif_err("Insufficent memory to allocate struct modem_data\n"); + err = -ENOMEM; + goto dt_parse_err; + } + + mc->link_pm_data = kzalloc(sizeof(struct modemlink_pm_data), GFP_KERNEL); + if (!mc->link_pm_data) { + mif_err("Insufficent memory to allocate struct modem_data\n"); + err = -ENOMEM; + goto dt_parse_err; + } + + mc->gpio_reset_req_n = of_get_named_gpio(np, "reset-req-gpio", 0); + if (!gpio_is_valid(mc->gpio_reset_req_n)) { + mif_err("failed to get reset-req gpio\n"); + err = -EINVAL; + goto dt_parse_err; + } + + mc->gpio_cp_on = of_get_named_gpio(np, "cp-on-gpio", 0); + if (!gpio_is_valid(mc->gpio_cp_on)) { + mif_err("failed to get cp-on gpio\n"); + err = -EINVAL; + goto dt_parse_err; + } + + mc->gpio_cp_reset = of_get_named_gpio(np, "cp-reset-gpio", 0); + if (!gpio_is_valid(mc->gpio_cp_reset)) { + mif_err("failed to get cp-reset gpio\n"); + err = -EINVAL; + goto dt_parse_err; + } + + mc->gpio_pda_active = of_get_named_gpio(np, "pda-active-gpio", 0); + if (!gpio_is_valid(mc->gpio_pda_active)) { + mif_err("failed to get pda-active gpio\n"); + err = -EINVAL; + goto dt_parse_err; + } + + mc->gpio_phone_active = of_get_named_gpio(np, "phone-active-gpio", 0); + if (!gpio_is_valid(mc->gpio_phone_active)) { + mif_err("failed to get phone-active gpio\n"); + err = -EINVAL; + goto dt_parse_err; + } + + mc->gpio_cp_dump_int = of_get_named_gpio(np, "cp-dump-int-gpio", 0); + if (!gpio_is_valid(mc->gpio_cp_dump_int)) { + mif_err("failed to get cp-dump-int gpio\n"); + err = -EINVAL; + goto dt_parse_err; + } + + mc->link_pm_data->gpio_link_slavewake = of_get_named_gpio(np, + "link-slavewake-gpio", 0); + if (!gpio_is_valid(mc->link_pm_data->gpio_link_slavewake)) { + mif_err("failed to get link-slavewak gpio\n"); + err = -EINVAL; + goto dt_parse_err; + } + + mc->link_pm_data->gpio_link_hostwake = of_get_named_gpio(np, + "link-hostwake-gpio", 0); + if (!gpio_is_valid(mc->link_pm_data->gpio_link_hostwake)) { + mif_err("failed to get link-hostwake gpio\n"); + err = -EINVAL; + goto dt_parse_err; + } + + mc->link_pm_data->gpio_link_active = of_get_named_gpio(np, "link-active-gpio", 0); + if (!gpio_is_valid(mc->link_pm_data->gpio_link_active)) { + mif_err("failed to get link-active gpio\n"); + err = -EINVAL; + goto dt_parse_err; + } + + mc->link_pm_data->gpio_link_enable = of_get_named_gpio(np, "link-enable-gpio", 0); + + /* link enable is optional */ +/* if (!gpio_is_valid(mc->link_pm_data->gpio_link_enable)) { + mif_err("failed to get link-enable gpio\n"); + return ERR_PTR(-EINVAL); + }*/ + + mc->link_pm_data->gpio_link_enable = 0; + + devm_gpio_request(&pdev->dev, mc->gpio_reset_req_n, "gpio_reset_req_n"); + devm_gpio_request(&pdev->dev, mc->gpio_cp_on, "gpio_cp_on"); + devm_gpio_request(&pdev->dev, mc->gpio_cp_reset, "gpio_cp_reset"); + devm_gpio_request(&pdev->dev, mc->gpio_pda_active, "gpio_pda_active"); + devm_gpio_request(&pdev->dev, mc->gpio_phone_active, "gpio_phone_active"); + devm_gpio_request(&pdev->dev, mc->gpio_cp_dump_int, "gpio_cp_dump_int"); + devm_gpio_request(&pdev->dev, mc->link_pm_data->gpio_link_slavewake, "gpio_link_slavewake"); + devm_gpio_request(&pdev->dev, mc->link_pm_data->gpio_link_hostwake, "gpio_link_hostwake"); + devm_gpio_request(&pdev->dev, mc->link_pm_data->gpio_link_active, "gpio_link_active"); + devm_gpio_request(&pdev->dev, mc->link_pm_data->gpio_link_enable, "gpio_link_enable"); + + platform_set_drvdata(pdev, mc); + + return mc; + +dt_parse_err: + if (mc && mc->link_pm_data) + free(mc->link_pm_data); + if (mc) + free(mc); + + return ERR_PTR(err); +} + static int modem_probe(struct platform_device *pdev) { - int i; + int i, ret; struct modem_data *pdata = pdev->dev.platform_data; struct modem_shared *msd = NULL; struct modem_ctl *modemctl = NULL; - struct io_device *iod[pdata->num_iodevs]; + struct io_device *iod[ARRAY_SIZE(umts_io_devices)]; struct link_device *ld; mif_err("%s\n", pdev->name); @@ -261,6 +475,22 @@ static int modem_probe(struct platform_device *pdev) goto err_free_modemctl; } + + pdata = modem_parse_dt(pdev, pdev->dev.of_node); + if (IS_ERR(pdata)) { + mif_err("Failed to parse device tree\n"); + kfree(msd); + return -ENOMEM; + } + + pdev->dev.platform_data = pdata; + + pdata->num_iodevs = ARRAY_SIZE(umts_io_devices); + pdata->iodevs = umts_io_devices; + pdata->modem_type = 1; + pdata->name = "xmm6262"; + pdata->link_types = LINKTYPE(LINKDEV_HSIC); + modemctl = create_modemctl_device(pdev, msd); if (!modemctl) { mif_err("modemctl == NULL\n"); @@ -352,10 +582,17 @@ static const struct dev_pm_ops modem_pm_ops = { .resume = modem_resume, }; +static const struct of_device_id modem_of_match[] = { + { .compatible = "samsung,modem_if" }, + {}, +}; +MODULE_DEVICE_TABLE(of, modem_of_match); + static struct platform_driver modem_driver = { .probe = modem_probe, .shutdown = modem_shutdown, .driver = { + .of_match_table = modem_of_match, .name = "modem_if", .pm = &modem_pm_ops, }, |