BigW Consortium Gitlab

Commit 50e58506 by David Frey

Add Red DV4 support to mangoh kernel module

parent 5b1d059a
......@@ -10,6 +10,7 @@ sources:
board_green_dv4.c
board_red_dv2.c
board_red_dv3.c
board_red_dv4.c
}
params:
......
......@@ -10,6 +10,7 @@ sources:
board_green_dv4.c
board_red_dv2.c
board_red_dv3.c
board_red_dv4.c
}
params:
......
......@@ -10,6 +10,7 @@ sources:
board_green_dv4.c
board_red_dv2.c
board_red_dv3.c
board_red_dv4.c
}
params:
......
cflags:
{
// Needed for lsm6ds3 platform data type definition
-I${MANGOH_ROOT}/linux_kernel_modules/lsm6ds3
}
sources:
{
mangoh_module.c
board_green_dv4.c
board_red_dv2.c
board_red_dv3.c
board_red_dv4.c
}
params:
{
board = "red dv4"
}
......@@ -171,14 +171,13 @@ static int red_dv2_map(struct platform_device *pdev)
* There is a driver in the WP85 kernel, but the gpiolib
* infrastructure of the WP85 kernel does not allow the expander
* GPIOs to be used in sysfs due to a hardcoded translation table.
* Pressure Sensor: 0x76
* chip is bmp280 by Bosch which has a driver in the mainline kernel
* 3503 USB Hub: 0x08
* Looks like there is a driver in the wp85 kernel source at drivers/usb/misc/usb3503.c
* I'm not really sure what benefit is achieved through using this driver.
* Battery Gauge: 0x64
* chip is LTC29421 which is made by linear technologies (now Analog
* Devices). I haven't found a linux kernel driver.
* chip is LTC2942 which is made by linear technologies (now Analog
* Devices). There is a kernel driver in the linux-power-supply
* repository in the for-next branch.
* Buck & Battery Charger: 0x6B
* chip is BQ24296RGER
*/
......
......@@ -42,7 +42,7 @@ static void red_dv3_release_device(struct device* dev);
*/
#define RED_DV3_I2C_SW_BASE_ADAPTER_ID (1)
#define RED_DV3_I2C_SW_PORT_IOT0 (0)
#define GREEN_DV4_I2C_SW_PORT_BATTERY_CHARGER (1)
#define RED_DV3_I2C_SW_PORT_BATTERY_CHARGER (1)
#define RED_DV3_I2C_SW_PORT_USB_HUB (1)
#define RED_DV3_I2C_SW_PORT_GPIO_EXPANDER (2)
#define RED_DV3_I2C_SW_PORT_EXP (3) /* expansion header */
......@@ -166,9 +166,6 @@ static int red_dv3_map(struct platform_device *pdev)
* 3503 USB Hub: 0x08
* Looks like there is a driver in the wp85 kernel source at drivers/usb/misc/usb3503.c
* I'm not really sure what benefit is achieved through using this driver.
* Battery Gauge: 0x64
* chip is LTC29421 which is made by linear technologies (now Analog
* Devices). I haven't found a linux kernel driver.
* Buck & Battery Charger: 0x6B
* chip is BQ24296RGER
*/
......
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/i2c/pca954x.h>
#include "mangoh.h"
#include "lsm6ds3_platform_data.h"
/*
*-----------------------------------------------------------------------------
* Type definitions
*-----------------------------------------------------------------------------
*/
struct red_dv4_platform_data {
struct i2c_client* i2c_switch;
struct i2c_client* accelerometer;
struct i2c_client* pressure;
};
struct red_dv4_device
{
struct platform_device pdev;
struct red_dv4_platform_data pdata;
};
/*
*-----------------------------------------------------------------------------
* Function declarations
*-----------------------------------------------------------------------------
*/
static int red_dv4_map(struct platform_device *pdev);
static int red_dv4_unmap(struct platform_device* pdev);
static void red_dv4_release_device(struct device* dev);
/*
*-----------------------------------------------------------------------------
* Constants
*-----------------------------------------------------------------------------
*/
#define RED_DV4_I2C_SW_BASE_ADAPTER_ID (1)
#define RED_DV4_I2C_SW_PORT_IOT0 (0)
#define RED_DV4_I2C_SW_PORT_BATTERY_CHARGER (1)
#define RED_DV4_I2C_SW_PORT_USB_HUB (1)
#define RED_DV4_I2C_SW_PORT_GPIO_EXPANDER (2)
#define RED_DV4_I2C_SW_PORT_EXP (3) /* expansion header */
/*
*-----------------------------------------------------------------------------
* Variables
*-----------------------------------------------------------------------------
*/
const struct mangoh_descriptor red_dv4_descriptor = {
.type = "mangoh red dv4",
.map = red_dv4_map,
.unmap = red_dv4_unmap,
};
static struct pca954x_platform_mode red_dv4_pca954x_adap_modes[] = {
{.adap_id=RED_DV4_I2C_SW_BASE_ADAPTER_ID + 0, .deselect_on_exit=1, .class=0},
{.adap_id=RED_DV4_I2C_SW_BASE_ADAPTER_ID + 1, .deselect_on_exit=1, .class=0},
{.adap_id=RED_DV4_I2C_SW_BASE_ADAPTER_ID + 2, .deselect_on_exit=1, .class=0},
{.adap_id=RED_DV4_I2C_SW_BASE_ADAPTER_ID + 3, .deselect_on_exit=1, .class=0},
};
static struct pca954x_platform_data red_dv4_pca954x_pdata = {
red_dv4_pca954x_adap_modes,
ARRAY_SIZE(red_dv4_pca954x_adap_modes),
};
static const struct i2c_board_info red_dv4_pca954x_device_info = {
I2C_BOARD_INFO("pca9546", 0x71),
.platform_data = &red_dv4_pca954x_pdata,
};
static struct i2c_board_info red_dv4_accelerometer_devinfo = {
I2C_BOARD_INFO("bmi160", 0x68),
};
static struct i2c_board_info red_dv4_pressure_devinfo = {
I2C_BOARD_INFO("bmp280", 0x76),
};
static const char platform_device_name[] = "mangoh red dv4";
/*
*-----------------------------------------------------------------------------
* Public function definitions
*-----------------------------------------------------------------------------
*/
int red_dv4_create_device(struct platform_device** d)
{
struct red_dv4_device *dv4 = kzalloc(sizeof(struct red_dv4_device), GFP_KERNEL);
if (!dv4)
return -ENOMEM;
dv4->pdev.name = platform_device_name;
dv4->pdev.id = -1;
dv4->pdev.dev.platform_data = &dv4->pdata;
dv4->pdev.dev.release = red_dv4_release_device;
*d = &dv4->pdev;
return 0;
}
/*
*-----------------------------------------------------------------------------
* Static function definitions
*-----------------------------------------------------------------------------
*/
static int red_dv4_map(struct platform_device *pdev)
{
struct red_dv4_platform_data* pdata = dev_get_platdata(&pdev->dev);
/* Get the main i2c adapter */
struct i2c_adapter* adapter = i2c_get_adapter(0);
if (!adapter) {
dev_err(&pdev->dev, "Failed to get I2C adapter 0.\n");
return -ENODEV;
}
/* Map the I2C switch */
dev_dbg(&pdev->dev, "mapping i2c switch\n");
pdata->i2c_switch = i2c_new_device(adapter, &red_dv4_pca954x_device_info);
if (!pdata->i2c_switch) {
dev_err(
&pdev->dev,
"Failed to register %s\n",
red_dv4_pca954x_device_info.type);
return -ENODEV;
}
/* Map the I2C BMI160 accelerometer */
dev_dbg(&pdev->dev, "mapping bmi160 accelerometer\n");
/*
* Pins 11 and 12 of the gpio expander are connected to bmi160's INT1
* and INT2 pins respectively. It does not appear that the bmi160 driver
* makes use of these interrupt pins.
*/
adapter = i2c_get_adapter(0);
if (!adapter) {
dev_err(&pdev->dev, "No I2C bus %d.\n", 0);
return -ENODEV;
}
pdata->accelerometer = i2c_new_device(adapter, &red_dv4_accelerometer_devinfo);
if (!pdata->accelerometer) {
dev_err(&pdev->dev, "Accelerometer is missing\n");
return -ENODEV;
}
/* Map the I2C BMP280 pressure sensor */
dev_dbg(&pdev->dev, "mapping bmp280 pressure sensor\n");
adapter = i2c_get_adapter(0);
if (!adapter) {
dev_err(&pdev->dev, "No I2C bus %d.\n", 0);
return -ENODEV;
}
pdata->pressure = i2c_new_device(adapter, &red_dv4_pressure_devinfo);
if (!pdata->pressure) {
dev_err(&pdev->dev, "Pressure sensor is missing\n");
return -ENODEV;
}
/*
* TODO:
* 3503 USB Hub: 0x08
* Looks like there is a driver in the wp85 kernel source at drivers/usb/misc/usb3503.c
* I'm not really sure what benefit is achieved through using this driver.
* Battery Gauge: 0x64
* chip is LTC2942 which is made by linear technologies (now Analog
* Devices). There is a kernel driver in the linux-power-supply
* repository in the for-next branch.
* Buck & Battery Charger: 0x6B
* chip is BQ24296RGER
*/
return 0;
}
static int red_dv4_unmap(struct platform_device* pdev)
{
struct red_dv4_platform_data* pdata = dev_get_platdata(&pdev->dev);
i2c_unregister_device(pdata->pressure);
i2c_put_adapter(pdata->pressure->adapter);
i2c_unregister_device(pdata->accelerometer);
i2c_put_adapter(pdata->accelerometer->adapter);
i2c_unregister_device(pdata->i2c_switch);
i2c_put_adapter(pdata->i2c_switch->adapter);
return 0;
}
static void red_dv4_release_device(struct device* dev)
{
struct platform_device *pdev = container_of(dev, struct platform_device, dev);
struct red_dv4_device *dv4 = container_of(pdev, struct red_dv4_device, pdev);
kfree(dv4);
}
#ifndef BOARD_RED_DV4_H
#define BOARD_RED_DV4_H
#include "mangoh.h"
extern const struct mangoh_descriptor red_dv4_descriptor;
int red_dv4_create_device(struct platform_device** d);
#endif // BOARD_RED_DV4_H
......@@ -9,6 +9,7 @@
#include "board_green_dv4.h"
#include "board_red_dv2.h"
#include "board_red_dv3.h"
#include "board_red_dv4.h"
/*
*-----------------------------------------------------------------------------
......@@ -42,6 +43,7 @@ static const struct platform_device_id mangoh_ids[] = {
{.name="mangoh green dv4", .driver_data=(kernel_ulong_t)&green_dv4_descriptor},
{.name="mangoh red dv2", .driver_data=(kernel_ulong_t)&red_dv2_descriptor},
{.name="mangoh red dv3", .driver_data=(kernel_ulong_t)&red_dv3_descriptor},
{.name="mangoh red dv4", .driver_data=(kernel_ulong_t)&red_dv4_descriptor},
{},
};
MODULE_DEVICE_TABLE(platform, mangoh_ids);
......@@ -92,6 +94,15 @@ static int __init mangoh_init(void)
board);
return rc;
}
} else if (strcmp(board, "red dv4") == 0) {
int rc = red_dv4_create_device(&mangoh_device);
if (rc != 0) {
pr_err(
"%s: Couldn't create device for '%s'.\n",
__func__,
board);
return rc;
}
} else {
pr_err(
"%s: unsupported board '%s'.\n",
......@@ -147,5 +158,5 @@ module_exit(mangoh_exit);
MODULE_ALIAS(PLATFORM_MODULE_PREFIX "mangoh");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sierra Wireless");
MODULE_DESCRIPTION("Add devices on mangOH green hardware board");
MODULE_DESCRIPTION("Add devices on mangOH hardware boards");
MODULE_VERSION("1.0");
......@@ -34,8 +34,9 @@ commands:
kernelModules:
{
$MANGOH_ROOT/linux_kernel_modules/mangoh/9-mangoh_red_dv3
// $MANGOH_ROOT/linux_kernel_modules/mangoh/9-mangoh_red_dv2
// $MANGOH_ROOT/linux_kernel_modules/mangoh/9-mangoh_red_dv3
$MANGOH_ROOT/linux_kernel_modules/mangoh/9-mangoh_red_dv4
// Disable the cp2130 for now until the lockup issue is resolved
// $MANGOH_ROOT/linux_kernel_modules/cp2130/0-cp2130
......@@ -49,11 +50,11 @@ kernelModules:
$MANGOH_ROOT/linux_kernel_modules/bmp280/2-bmp280
$MANGOH_ROOT/linux_kernel_modules/bmp280/3-bmp280-i2c
// Only on mangOH Red DV2
// Used on mangOH Red DV2
// $MANGOH_ROOT/linux_kernel_modules/lsm6ds3/0-lsm6ds3
// $MANGOH_ROOT/linux_kernel_modules/lsm6ds3/1-lsm6ds3-i2c
// Only on mangOH Red DV3
// Used on mangOH Red DV3 and later
$MANGOH_ROOT/linux_kernel_modules/bmi160/3-bmi160
$MANGOH_ROOT/linux_kernel_modules/bmi160/4-bmi160-i2c
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment