lkml.org 
[lkml]   [2011]   [Jul]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/5] x86: base support for TS-5500 Single Board Computer
    Date
    Add base support for TS-5500 in arch/x86/platform/ts5500 and documentation in
    Documentation/ABI/testing/sysfs-platform-ts5500.

    Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
    ---
    Documentation/ABI/testing/sysfs-platform-ts5500 | 46 ++++
    MAINTAINERS | 7 +
    arch/x86/Kconfig | 2 +
    arch/x86/platform/Makefile | 1 +
    arch/x86/platform/ts5500/Kconfig | 7 +
    arch/x86/platform/ts5500/Makefile | 1 +
    arch/x86/platform/ts5500/ts5500.c | 296 +++++++++++++++++++++++
    7 files changed, 360 insertions(+), 0 deletions(-)
    create mode 100644 Documentation/ABI/testing/sysfs-platform-ts5500
    create mode 100644 arch/x86/platform/ts5500/Kconfig
    create mode 100644 arch/x86/platform/ts5500/Makefile
    create mode 100644 arch/x86/platform/ts5500/ts5500.c

    diff --git a/Documentation/ABI/testing/sysfs-platform-ts5500 b/Documentation/ABI/testing/sysfs-platform-ts5500
    new file mode 100644
    index 0000000..c870564
    --- /dev/null
    +++ b/Documentation/ABI/testing/sysfs-platform-ts5500
    @@ -0,0 +1,46 @@
    +What: /sys/devices/platform/ts5500/id
    +Date: July 2011
    +KernelVersion: 2.6.39
    +Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
    +Description:
    + Product ID of the TS board. TS-5500 ID is 0x60.
    +
    +What: /sys/devices/platform/ts5500/sram
    +Date: July 2011
    +KernelVersion: 2.6.39
    +Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
    +Description:
    + Say if the SRAM feature is present. If it is enabled, it will
    + display "1", otherwise "0".
    +
    +What: /sys/devices/platform/ts5500/ereset
    +Date: July 2011
    +KernelVersion: 2.6.39
    +Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
    +Description:
    + Say if an external reset is present. If it is present, it will
    + display "1", otherwise "0".
    +
    +What: /sys/devices/platform/ts5500/jp{1,2,3,4,5,6}
    +Date: July 2011
    +KernelVersion: 2.6.39
    +Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
    +Description:
    + Show the state of a plugged jumper. If it is present, it will
    + display "1", otherwise "0".
    +
    +What: /sys/devices/platform/ts5500/adc
    +Date: July 2011
    +KernelVersion: 2.6.39
    +Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
    +Description:
    + Say if the Analogic to Digital Converter is present. If it is
    + enabled, it will display "1", otherwise "0".
    +
    +What: /sys/devices/platform/ts5500/rs485
    +Date: July 2011
    +KernelVersion: 2.6.39
    +Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
    +Description:
    + Say if the RS485 feature is present. If it is enabled, it
    + will display "1", otherwise "0".
    \ No newline at end of file
    diff --git a/MAINTAINERS b/MAINTAINERS
    index 187282d..be8ce4b 100644
    --- a/MAINTAINERS
    +++ b/MAINTAINERS
    @@ -6134,6 +6134,13 @@ W: http://tcp-lp-mod.sourceforge.net/
    S: Maintained
    F: net/ipv4/tcp_lp.c

    +TECHNOLOGIC SYSTEMS TS5500 MACHINE SUPPORT
    +M: Savoir-faire Linux Inc. <ts-kernel@savoirfairelinux.com>
    +S: Maintained
    +F: arch/x86/platform/ts5500/Kconfig
    +F: arch/x86/platform/ts5500/Makefile
    +F: arch/x86/platform/ts5500/ts5500.c
    +
    TEGRA SUPPORT
    M: Colin Cross <ccross@android.com>
    M: Erik Gilling <konkers@android.com>
    diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
    index da34972..cd4bf1a 100644
    --- a/arch/x86/Kconfig
    +++ b/arch/x86/Kconfig
    @@ -2079,6 +2079,8 @@ config OLPC_XO1
    ---help---
    Add support for non-essential features of the OLPC XO-1 laptop.

    +source "arch/x86/platform/ts5500/Kconfig"
    +
    endif # X86_32

    config AMD_NB
    diff --git a/arch/x86/platform/Makefile b/arch/x86/platform/Makefile
    index 021eee9..1bdc038 100644
    --- a/arch/x86/platform/Makefile
    +++ b/arch/x86/platform/Makefile
    @@ -8,3 +8,4 @@ obj-y += scx200/
    obj-y += sfi/
    obj-y += visws/
    obj-y += uv/
    +obj-y += ts5500/
    diff --git a/arch/x86/platform/ts5500/Kconfig b/arch/x86/platform/ts5500/Kconfig
    new file mode 100644
    index 0000000..6428ca5
    --- /dev/null
    +++ b/arch/x86/platform/ts5500/Kconfig
    @@ -0,0 +1,7 @@
    +config TS5500
    + bool "Technologic Systems TS-5500 Single Board Computer support"
    + depends on MELAN
    + help
    + Add support for the Technologic Systems TS-5500 platform features.
    +
    + If you have a TS-5500, say Y here.
    diff --git a/arch/x86/platform/ts5500/Makefile b/arch/x86/platform/ts5500/Makefile
    new file mode 100644
    index 0000000..0a689a7
    --- /dev/null
    +++ b/arch/x86/platform/ts5500/Makefile
    @@ -0,0 +1 @@
    +obj-$(CONFIG_TS5500) += ts5500.o
    diff --git a/arch/x86/platform/ts5500/ts5500.c b/arch/x86/platform/ts5500/ts5500.c
    new file mode 100644
    index 0000000..0135dbd
    --- /dev/null
    +++ b/arch/x86/platform/ts5500/ts5500.c
    @@ -0,0 +1,296 @@
    +/*
    + * Technologic Systems TS-5500 board - SBC info layer
    + *
    + * Copyright (c) 2010-2011 Savoir-faire Linux Inc.
    + * Alexandre Savard <alexandre.savard@savoirfairelinux.com>
    + * Jonas Fonseca <jonas.fonseca@savoirfairelinux.com>
    + * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
    + *
    + * Portions originate from ts_sbcinfo.c (c) Technologic Systems
    + * Liberty Young <liberty@embeddedx86.com>
    + *
    + * These functions add sysfs platform entries to display information about
    + * the Technologic Systems TS-5500 Single Board Computer (SBC).
    + *
    + * For further information about sysfs entries, see
    + * Documentation/ABI/testing/sysfs-platform-ts5500
    + */
    +
    +#include <linux/module.h>
    +#include <linux/ioport.h>
    +#include <linux/platform_device.h>
    +#include <linux/kernel.h>
    +#include <linux/mutex.h>
    +#include <linux/io.h>
    +#include <linux/slab.h>
    +#include <asm/processor.h>
    +
    +/* Hardware info for pre-detection */
    +#define AMD_ELAN_FAMILY 4
    +#define AMD_ELAN_SC520 9
    +
    +/* Product code register */
    +#define TS5500_PRODUCT_CODE_REG 0x74
    +#define TS5500_PRODUCT_CODE 0x60 /* TS-5500 product code */
    +
    +/* SRAM/RS-485/ADC options, and RS-485 RTS/Automatic RS-485 flags register */
    +#define TS5500_SRAM_RS485_ADC_REG 0x75
    +#define TS5500_SRAM_OPT 0x01 /* SRAM option */
    +#define TS5500_RS485_OPT 0x02 /* RS-485 option */
    +#define TS5500_ADC_OPT 0x04 /* A/D converter option */
    +#define TS5500_RS485_RTS_FLAG 0x40 /* RTS for RS-485 */
    +#define TS5500_RS485_AUTO_FLAG 0x80 /* Automatic RS-485 */
    +
    +/* External Reset/Industrial Temperature Range options register */
    +#define TS5500_ERESET_ITR_REG 0x76
    +#define TS5500_ERESET_OPT 0x01 /* External Reset option */
    +#define TS5500_ITR_OPT 0x02 /* Indust. Temp. Range option */
    +
    +/* LED/Jumpers register */
    +#define TS5500_LED_JMPRS_REG 0x77
    +#define TS5500_LED_FLAG 0x01 /* LED flag */
    +#define TS5500_JP1 0x02 /* Automatic CMOS */
    +#define TS5500_JP2 0x04 /* Enable Serial Console */
    +#define TS5500_JP3 0x08 /* Write Enable Drive A */
    +#define TS5500_JP4 0x10 /* Fast Console (115K baud) */
    +#define TS5500_JP5 0x20 /* User Jumper */
    +#define TS5500_JP6 0x40 /* Console on COM1 (req. JP2) */
    +#define TS5500_JP7 0x80 /* Undocumented (Unused) */
    +
    +/**
    + * struct ts5500_sbc - TS-5500 SBC main structure
    + * @lock: Read/Write mutex.
    + * @board_id: Board name.
    + * @sram: Check SRAM option.
    + * @rs485: Check RS-485 option.
    + * @adc: Check Analogic/Digital converter option.
    + * @ereset: Check External Reset option.
    + * @itr: Check Industrial Temperature Range option.
    + * @jumpers: States of jumpers 1-7.
    + */
    +struct ts5500_sbc {
    + struct mutex lock;
    + int board_id;
    + bool sram;
    + bool rs485;
    + bool adc;
    + bool ereset;
    + bool itr;
    + u8 jumpers;
    +};
    +
    +/* Current platform */
    +struct ts5500_sbc *ts5500;
    +
    +/**
    + * ts5500_pre_detect() - check for TS-5500 specific features
    + *
    + * It is not safe to read ID register if we are not sure that it's a TS SBC.
    + * Since TS SBCs don't have DMI support, it is safer to check for a TS-5500
    + * specific feature such as the processor.
    + */
    +static int ts5500_pre_detect(void)
    +{
    + /* Check for AMD ElanSC520 Microcontroller */
    + if (!(cpu_info.x86_vendor == X86_VENDOR_AMD &&
    + cpu_info.x86 == AMD_ELAN_FAMILY &&
    + cpu_info.x86_model == AMD_ELAN_SC520))
    + return -ENODEV;
    +
    + return 0;
    +}
    +
    +/**
    + * ts5500_detect_config() - detect the TS board
    + * @sbc: Structure where to store the detected board's details.
    + */
    +static int ts5500_detect_config(struct ts5500_sbc *sbc)
    +{
    + u8 tmp;
    + int ret = 0;
    +
    + if (!request_region(TS5500_PRODUCT_CODE_REG, 4, "ts5500"))
    + return -EBUSY;
    +
    + mutex_lock(&ts5500->lock);
    + tmp = inb(TS5500_PRODUCT_CODE_REG);
    + if (tmp != TS5500_PRODUCT_CODE) {
    + pr_err("This platform is not a TS-5500 (found ID 0x%x)\n", tmp);
    + ret = -ENODEV;
    + goto error;
    + }
    + sbc->board_id = tmp;
    +
    + tmp = inb(TS5500_SRAM_RS485_ADC_REG);
    + ts5500->sram = !!(tmp & TS5500_SRAM_OPT);
    + ts5500->rs485 = !!(tmp & TS5500_RS485_OPT);
    + ts5500->adc = !!(tmp & TS5500_ADC_OPT);
    +
    + tmp = inb(TS5500_ERESET_ITR_REG);
    + ts5500->ereset = !!(tmp & TS5500_ERESET_OPT);
    + ts5500->itr = !!(tmp & TS5500_ITR_OPT);
    +
    + tmp = inb(TS5500_LED_JMPRS_REG);
    + sbc->jumpers = tmp & 0xFE; /* All bits except the first (LED) */
    +
    +error:
    + mutex_unlock(&ts5500->lock);
    + release_region(TS5500_PRODUCT_CODE_REG, 4);
    + return ret;
    +}
    +
    +#define TS5500_IS_JP_SET(sbc, jmp) (!!(sbc->jumpers & TS5500_JP##jmp))
    +
    +static struct platform_device *ts5500_devices[] __initdata = {
    +};
    +
    +static ssize_t ts5500_show_id(struct device *dev,
    + struct device_attribute *attr, char *buf)
    +{
    + struct ts5500_sbc *sbc = dev_get_drvdata(dev);
    +
    + return sprintf(buf, "0x%x\n", sbc->board_id);
    +}
    +
    +static ssize_t ts5500_show_sram(struct device *dev,
    + struct device_attribute *attr, char *buf)
    +{
    + struct ts5500_sbc *sbc = dev_get_drvdata(dev);
    +
    + return sprintf(buf, "%d\n", sbc->sram);
    +}
    +
    +static ssize_t ts5500_show_rs485(struct device *dev,
    + struct device_attribute *attr, char *buf)
    +{
    + struct ts5500_sbc *sbc = dev_get_drvdata(dev);
    +
    + return sprintf(buf, "%d\n", sbc->rs485);
    +}
    +
    +static ssize_t ts5500_show_adc(struct device *dev,
    + struct device_attribute *attr, char *buf)
    +{
    + struct ts5500_sbc *sbc = dev_get_drvdata(dev);
    +
    + return sprintf(buf, "%d\n", sbc->adc);
    +}
    +
    +static ssize_t ts5500_show_ereset(struct device *dev,
    + struct device_attribute *attr,
    + char *buf)
    +{
    + struct ts5500_sbc *sbc = dev_get_drvdata(dev);
    +
    + return sprintf(buf, "%d\n", sbc->ereset);
    +}
    +
    +static ssize_t ts5500_show_itr(struct device *dev,
    + struct device_attribute *attr,
    + char *buf)
    +{
    + struct ts5500_sbc *sbc = dev_get_drvdata(dev);
    +
    + return sprintf(buf, "%d\n", sbc->itr);
    +}
    +
    +#define TS5500_SHOW_JP(jp) \
    + static ssize_t ts5500_show_jp##jp(struct device *dev, \
    + struct device_attribute *attr,\
    + char *buf) \
    + { \
    + struct ts5500_sbc *sbc = dev_get_drvdata(dev); \
    + return sprintf(buf, "%d\n", TS5500_IS_JP_SET(sbc, jp)); \
    + }
    +
    +TS5500_SHOW_JP(1)
    +TS5500_SHOW_JP(2)
    +TS5500_SHOW_JP(3)
    +TS5500_SHOW_JP(4)
    +TS5500_SHOW_JP(5)
    +TS5500_SHOW_JP(6)
    +
    +static DEVICE_ATTR(id, S_IRUGO, ts5500_show_id, NULL);
    +static DEVICE_ATTR(sram, S_IRUGO, ts5500_show_sram, NULL);
    +static DEVICE_ATTR(rs485, S_IRUGO, ts5500_show_rs485, NULL);
    +static DEVICE_ATTR(adc, S_IRUGO, ts5500_show_adc, NULL);
    +static DEVICE_ATTR(ereset, S_IRUGO, ts5500_show_ereset, NULL);
    +static DEVICE_ATTR(itr, S_IRUGO, ts5500_show_itr, NULL);
    +static DEVICE_ATTR(jp1, S_IRUGO, ts5500_show_jp1, NULL);
    +static DEVICE_ATTR(jp2, S_IRUGO, ts5500_show_jp2, NULL);
    +static DEVICE_ATTR(jp3, S_IRUGO, ts5500_show_jp3, NULL);
    +static DEVICE_ATTR(jp4, S_IRUGO, ts5500_show_jp4, NULL);
    +static DEVICE_ATTR(jp5, S_IRUGO, ts5500_show_jp5, NULL);
    +static DEVICE_ATTR(jp6, S_IRUGO, ts5500_show_jp6, NULL);
    +
    +static struct attribute *ts5500_attributes[] = {
    + &dev_attr_id.attr,
    + &dev_attr_sram.attr,
    + &dev_attr_rs485.attr,
    + &dev_attr_adc.attr,
    + &dev_attr_ereset.attr,
    + &dev_attr_itr.attr,
    + &dev_attr_jp1.attr,
    + &dev_attr_jp2.attr,
    + &dev_attr_jp3.attr,
    + &dev_attr_jp4.attr,
    + &dev_attr_jp5.attr,
    + &dev_attr_jp6.attr,
    + NULL
    +};
    +
    +static const struct attribute_group ts5500_attr_group = {
    + .attrs = ts5500_attributes
    +};
    +
    +static int __init ts5500_init(void)
    +{
    + int ret;
    + struct platform_device *pdev;
    +
    + /* Firstly, check specific TS-5500 hardware, such as CPU. */
    + ret = ts5500_pre_detect();
    + if (ret)
    + return ret;
    +
    + ts5500 = kzalloc(sizeof(struct ts5500_sbc), GFP_KERNEL);
    + if (!ts5500)
    + return -ENOMEM;
    + mutex_init(&ts5500->lock);
    +
    + ret = ts5500_detect_config(ts5500);
    + if (ret)
    + goto release_mem;
    +
    + pdev = platform_device_register_simple("ts5500", -1, NULL, 0);
    + if (IS_ERR(pdev)) {
    + ret = PTR_ERR(pdev);
    + goto release_mem;
    + }
    + platform_set_drvdata(pdev, ts5500);
    +
    + ret = platform_add_devices(ts5500_devices, ARRAY_SIZE(ts5500_devices));
    + if (ret)
    + goto release_pdev;
    +
    + ret = sysfs_create_group(&pdev->dev.kobj,
    + &ts5500_attr_group);
    + if (ret)
    + goto release_pdev;
    +
    + return 0;
    +
    +release_pdev:
    + platform_device_unregister(pdev);
    +release_mem:
    + kfree(ts5500);
    +
    + return ret;
    +}
    +postcore_initcall(ts5500_init);
    +
    +MODULE_AUTHOR("Jonas Fonseca <jonas.fonseca@savoirfairelinux.com>");
    +MODULE_AUTHOR("Alexandre Savard <alexandre.savard@savoirfairelinux.com>");
    +MODULE_AUTHOR("Vivien Didelot <vivien.didelot@savoirfairelinux.com>");
    +MODULE_DESCRIPTION("Technologic Systems TS-5500 Board's platform driver");
    +MODULE_LICENSE("GPL");
    --
    1.7.6


    \
     
     \ /
      Last update: 2011-07-19 22:07    [W:0.044 / U:29.968 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site