Revision e2921f9f95f1c1355a39e54dc038ad95b6e032be authored by Linus Torvalds on 26 July 2019, 21:12:54 UTC, committed by Linus Torvalds on 26 July 2019, 21:12:54 UTC
Pull drm fixes from Daniel Vetter: "Dave seems to collect an entire streak of things happening, so again me typing pull summary. Nothing nefarious here, most of the fixes are for new stuff or things users won't see. The amd-display patches are a bit different, and very much look like they should have at least some cc: stable tags. Might be amd is a bit too comfortable with their internal tree and not enough looking at upstream. Dave&me are looking into this, in case something needs rectified with process here. Also no intel fixes pull, but intel CI is general become rather good, still I guess expect a notch more for -rc3. Summary: amdgpu: - fixes for (new in 5.3) hw support (vega20, navi) - disable RAS - lots of display fixes all over (audio, DSC, dongle, clock mgr) ttm: - fix dma_free_attrs calls to appease dma debugging msm: - fixes for dma-api, locking debug and compiler splats core: - fix cmdline mode to not apply rotation if not specified (new in 5.3) - compiler warn fix" * tag 'drm-fixes-2019-07-26' of git://anongit.freedesktop.org/drm/drm: (46 commits) drm/amd/display: Set enabled to false at start of audio disable drm/amdgpu/smu: move fan rpm query into the asic specific code drm/amd/powerplay: custom peak clock freq for navi10 drm: silence variable 'conn' set but not used drm/msm: stop abusing dma_map/unmap for cache drm/msm/dpu: Correct dpu encoder spinlock initialization drm/msm: correct NULL pointer dereference in context_init drm/amd/display: handle active dongle port type is DP++ or DP case drm/amd/display: do not read link setting if edp not connected drm/amd/display: Increase size of audios array drm/amd/display: drop ASSERT() if eDP panel is not connected drm/amd/display: Only enable audio if speaker allocation exists drm/amd/display: Fix dc_create failure handling and 666 color depths drm/amd/display: allocate 4 ddc engines for RV2 drm/amd/display: put back front end initialization sequence drm/amd/display: Wait for flip to complete drm/amd/display: Change min_h_sync_width from 8 to 4 drm/amd/display: use encoder's engine id to find matched free audio device drm/amd/display: fix DMCU hang when going into Modern Standby drm/amd/display: Disable Audio on reinitialize hardware ...
mcp3021.c
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* mcp3021.c - driver for Microchip MCP3021 and MCP3221
*
* Copyright (C) 2008-2009, 2012 Freescale Semiconductor, Inc.
* Author: Mingkai Hu <Mingkai.hu@freescale.com>
* Reworked by Sven Schuchmann <schuchmann@schleissheimer.de>
* DT support added by Clemens Gruber <clemens.gruber@pqgruber.com>
*
* This driver export the value of analog input voltage to sysfs, the
* voltage unit is mV. Through the sysfs interface, lm-sensors tool
* can also display the input voltage.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hwmon.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_device.h>
/* Vdd / reference voltage in millivolt */
#define MCP3021_VDD_REF_MAX 5500
#define MCP3021_VDD_REF_MIN 2700
#define MCP3021_VDD_REF_DEFAULT 3300
/* output format */
#define MCP3021_SAR_SHIFT 2
#define MCP3021_SAR_MASK 0x3ff
#define MCP3021_OUTPUT_RES 10 /* 10-bit resolution */
#define MCP3221_SAR_SHIFT 0
#define MCP3221_SAR_MASK 0xfff
#define MCP3221_OUTPUT_RES 12 /* 12-bit resolution */
enum chips {
mcp3021,
mcp3221
};
/*
* Client data (each client gets its own)
*/
struct mcp3021_data {
struct device *hwmon_dev;
u32 vdd; /* supply and reference voltage in millivolt */
u16 sar_shift;
u16 sar_mask;
u8 output_res;
};
static int mcp3021_read16(struct i2c_client *client)
{
struct mcp3021_data *data = i2c_get_clientdata(client);
int ret;
u16 reg;
__be16 buf;
ret = i2c_master_recv(client, (char *)&buf, 2);
if (ret < 0)
return ret;
if (ret != 2)
return -EIO;
/* The output code of the MCP3021 is transmitted with MSB first. */
reg = be16_to_cpu(buf);
/*
* The ten-bit output code is composed of the lower 4-bit of the
* first byte and the upper 6-bit of the second byte.
*/
reg = (reg >> data->sar_shift) & data->sar_mask;
return reg;
}
static inline u16 volts_from_reg(struct mcp3021_data *data, u16 val)
{
return DIV_ROUND_CLOSEST(data->vdd * val, 1 << data->output_res);
}
static ssize_t in0_input_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct mcp3021_data *data = i2c_get_clientdata(client);
int reg, in_input;
reg = mcp3021_read16(client);
if (reg < 0)
return reg;
in_input = volts_from_reg(data, reg);
return sprintf(buf, "%d\n", in_input);
}
static DEVICE_ATTR_RO(in0_input);
static int mcp3021_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err;
struct mcp3021_data *data = NULL;
struct device_node *np = client->dev.of_node;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
data = devm_kzalloc(&client->dev, sizeof(struct mcp3021_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
if (np) {
if (!of_property_read_u32(np, "reference-voltage-microvolt",
&data->vdd))
data->vdd /= 1000;
else
data->vdd = MCP3021_VDD_REF_DEFAULT;
} else {
u32 *pdata = dev_get_platdata(&client->dev);
if (pdata)
data->vdd = *pdata;
else
data->vdd = MCP3021_VDD_REF_DEFAULT;
}
switch (id->driver_data) {
case mcp3021:
data->sar_shift = MCP3021_SAR_SHIFT;
data->sar_mask = MCP3021_SAR_MASK;
data->output_res = MCP3021_OUTPUT_RES;
break;
case mcp3221:
data->sar_shift = MCP3221_SAR_SHIFT;
data->sar_mask = MCP3221_SAR_MASK;
data->output_res = MCP3221_OUTPUT_RES;
break;
}
if (data->vdd > MCP3021_VDD_REF_MAX || data->vdd < MCP3021_VDD_REF_MIN)
return -EINVAL;
err = sysfs_create_file(&client->dev.kobj, &dev_attr_in0_input.attr);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr);
return err;
}
static int mcp3021_remove(struct i2c_client *client)
{
struct mcp3021_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr);
return 0;
}
static const struct i2c_device_id mcp3021_id[] = {
{ "mcp3021", mcp3021 },
{ "mcp3221", mcp3221 },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp3021_id);
#ifdef CONFIG_OF
static const struct of_device_id of_mcp3021_match[] = {
{ .compatible = "microchip,mcp3021", .data = (void *)mcp3021 },
{ .compatible = "microchip,mcp3221", .data = (void *)mcp3221 },
{ }
};
MODULE_DEVICE_TABLE(of, of_mcp3021_match);
#endif
static struct i2c_driver mcp3021_driver = {
.driver = {
.name = "mcp3021",
.of_match_table = of_match_ptr(of_mcp3021_match),
},
.probe = mcp3021_probe,
.remove = mcp3021_remove,
.id_table = mcp3021_id,
};
module_i2c_driver(mcp3021_driver);
MODULE_AUTHOR("Mingkai Hu <Mingkai.hu@freescale.com>");
MODULE_DESCRIPTION("Microchip MCP3021/MCP3221 driver");
MODULE_LICENSE("GPL");
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...