drivers/i2c: Add a driver for Semtech SX9310
This adds a new driver for the SX9310 proximity detector device. The purpose of this is to enable the device's calibration information to be stored in firmware, and then transferred over to the kernel via ACPI. This device has more than 10 individual configuration parameters, so they would not fit in the generic driver's properties table. Change-Id: Id8c434eec9fe2da731e142442503a12e88db2236 Signed-off-by: Enrico Granata <egranata@chromium.org> Reviewed-on: https://review.coreboot.org/27173 Reviewed-by: Furquan Shaikh <furquan@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
9700e91b10
commit
76a1f49f74
5 changed files with 190 additions and 0 deletions
6
src/drivers/i2c/sx9310/Kconfig
Normal file
6
src/drivers/i2c/sx9310/Kconfig
Normal file
|
@ -0,0 +1,6 @@
|
|||
config DRIVERS_I2C_SX9310
|
||||
bool
|
||||
default n
|
||||
depends on HAVE_ACPI_TABLES
|
||||
help
|
||||
Board has a Semtech SX9310 proximity sensor.
|
1
src/drivers/i2c/sx9310/Makefile.inc
Normal file
1
src/drivers/i2c/sx9310/Makefile.inc
Normal file
|
@ -0,0 +1 @@
|
|||
ramstage-$(CONFIG_DRIVERS_I2C_SX9310) += sx9310.c
|
34
src/drivers/i2c/sx9310/chip.h
Normal file
34
src/drivers/i2c/sx9310/chip.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_I2C_SX9310_CHIP_H__
|
||||
#define __DRIVERS_I2C_SX9310_CHIP_H__
|
||||
|
||||
#include <arch/acpi_device.h>
|
||||
#include <device/i2c_simple.h>
|
||||
|
||||
#define REGISTER(NAME) uint8_t NAME
|
||||
|
||||
struct drivers_i2c_sx9310_config {
|
||||
const char *desc; /* Device Description */
|
||||
unsigned int uid; /* ACPI _UID */
|
||||
enum i2c_speed speed; /* Bus speed in Hz, default is I2C_SPEED_FAST */
|
||||
struct acpi_irq irq; /* Interrupt */
|
||||
#include "registers.h"
|
||||
};
|
||||
|
||||
#undef REGISTER
|
||||
|
||||
#endif /* __DRIVERS_I2C_SX9310_CHIP_H__ */
|
42
src/drivers/i2c/sx9310/registers.h
Normal file
42
src/drivers/i2c/sx9310/registers.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef REGISTER
|
||||
#error "define REGISTER(NAME) before including this file"
|
||||
#endif
|
||||
|
||||
REGISTER(reg_prox_ctrl0);
|
||||
REGISTER(reg_prox_ctrl1);
|
||||
REGISTER(reg_prox_ctrl2);
|
||||
REGISTER(reg_prox_ctrl3);
|
||||
REGISTER(reg_prox_ctrl4);
|
||||
REGISTER(reg_prox_ctrl5);
|
||||
REGISTER(reg_prox_ctrl6);
|
||||
REGISTER(reg_prox_ctrl7);
|
||||
REGISTER(reg_prox_ctrl8);
|
||||
REGISTER(reg_prox_ctrl9);
|
||||
REGISTER(reg_prox_ctrl10);
|
||||
REGISTER(reg_prox_ctrl11);
|
||||
REGISTER(reg_prox_ctrl12);
|
||||
REGISTER(reg_prox_ctrl13);
|
||||
REGISTER(reg_prox_ctrl14);
|
||||
REGISTER(reg_prox_ctrl15);
|
||||
REGISTER(reg_prox_ctrl16);
|
||||
REGISTER(reg_prox_ctrl17);
|
||||
REGISTER(reg_prox_ctrl18);
|
||||
REGISTER(reg_prox_ctrl19);
|
||||
REGISTER(reg_sar_ctrl0);
|
||||
REGISTER(reg_sar_ctrl1);
|
||||
REGISTER(reg_sar_ctrl2);
|
107
src/drivers/i2c/sx9310/sx9310.c
Normal file
107
src/drivers/i2c/sx9310/sx9310.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arch/acpi_device.h>
|
||||
#include <arch/acpigen.h>
|
||||
#include <device/i2c_simple.h>
|
||||
#include <device/device.h>
|
||||
#include <device/path.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "chip.h"
|
||||
|
||||
#define I2C_SX9310_ACPI_ID "SX9310"
|
||||
#define I2C_SX9310_ACPI_NAME "Semtech SX9310"
|
||||
|
||||
#define REGISTER(NAME) acpi_dp_add_integer(dsd, \
|
||||
I2C_SX9310_ACPI_ID "," #NAME, \
|
||||
config->NAME)
|
||||
|
||||
static void i2c_sx9310_fill_ssdt(struct device *dev)
|
||||
{
|
||||
struct drivers_i2c_sx9310_config *config = dev->chip_info;
|
||||
const char *scope = acpi_device_scope(dev);
|
||||
struct acpi_i2c i2c = {
|
||||
.address = dev->path.i2c.device,
|
||||
.mode_10bit = dev->path.i2c.mode_10bit,
|
||||
.speed = config->speed ? : I2C_SPEED_FAST,
|
||||
.resource = scope,
|
||||
};
|
||||
struct acpi_dp *dsd;
|
||||
|
||||
if (!dev->enabled || !scope || !config)
|
||||
return;
|
||||
|
||||
/* Device */
|
||||
acpigen_write_scope(scope);
|
||||
acpigen_write_device(acpi_device_name(dev));
|
||||
acpigen_write_name_string("_HID", I2C_SX9310_ACPI_ID);
|
||||
acpigen_write_name_integer("_UID", config->uid);
|
||||
acpigen_write_name_string("_DDN", config->desc);
|
||||
acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
|
||||
|
||||
/* Resources */
|
||||
acpigen_write_name("_CRS");
|
||||
acpigen_write_resourcetemplate_header();
|
||||
acpi_device_write_i2c(&i2c);
|
||||
acpi_device_write_interrupt(&config->irq);
|
||||
acpigen_write_resourcetemplate_footer();
|
||||
|
||||
/* DSD */
|
||||
dsd = acpi_dp_new_table("_DSD");
|
||||
#include "registers.h"
|
||||
acpi_dp_write(dsd);
|
||||
|
||||
acpigen_pop_len(); /* Device */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
#undef REGISTER
|
||||
|
||||
static const char *i2c_sx9310_acpi_name(const struct device *dev)
|
||||
{
|
||||
static char name[5];
|
||||
|
||||
snprintf(name, sizeof(name), "D%03.3X", dev->path.i2c.device);
|
||||
return name;
|
||||
}
|
||||
|
||||
static struct device_operations i2c_sx9310_ops = {
|
||||
.read_resources = DEVICE_NOOP,
|
||||
.set_resources = DEVICE_NOOP,
|
||||
.enable_resources = DEVICE_NOOP,
|
||||
.acpi_name = &i2c_sx9310_acpi_name,
|
||||
.acpi_fill_ssdt_generator = &i2c_sx9310_fill_ssdt,
|
||||
};
|
||||
|
||||
static void i2c_sx9310_enable(struct device *dev)
|
||||
{
|
||||
struct drivers_i2c_sx9310_config *config = dev->chip_info;
|
||||
|
||||
if (!config) {
|
||||
dev->enabled = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
dev->ops = &i2c_sx9310_ops;
|
||||
|
||||
if (config->desc)
|
||||
dev->name = config->desc;
|
||||
}
|
||||
|
||||
struct chip_operations drivers_i2c_sx9310_ops = {
|
||||
CHIP_NAME(I2C_SX9310_ACPI_NAME)
|
||||
.enable_dev = &i2c_sx9310_enable
|
||||
};
|
Loading…
Reference in a new issue