Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0996aea authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/gpio: port gpio to subdev interfaces



v2: Ben Skeggs <bskeggs@redhat.com>
- rebase on top of v3.6-rc6 with gpio reset patch integrated already

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent cd42439d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ nouveau-y += core/core/subdev.o

nouveau-y += core/subdev/bios/base.o
nouveau-y += core/subdev/bios/bit.o
nouveau-y += core/subdev/bios/dcb.o
nouveau-y += core/subdev/bios/gpio.o
nouveau-y += core/subdev/device/base.o
nouveau-y += core/subdev/device/nv04.o
nouveau-y += core/subdev/device/nv10.o
@@ -41,6 +43,7 @@ nouveau-y += core/subdev/fb/nvc0_vram.o
nouveau-y += core/subdev/gpio/base.o
nouveau-y += core/subdev/gpio/nv10.o
nouveau-y += core/subdev/gpio/nv50.o
nouveau-y += core/subdev/gpio/nvd0.o
nouveau-y += core/subdev/i2c/base.o
nouveau-y += core/subdev/instmem/nv04.o
nouveau-y += core/subdev/instmem/nv50.o
+19 −0
Original line number Diff line number Diff line
#ifndef __NVBIOS_DCB_H__
#define __NVBIOS_DCB_H__

enum dcb_output_type {
	DCB_OUTPUT_ANALOG	= 0x0,
	DCB_OUTPUT_TV		= 0x1,
	DCB_OUTPUT_TMDS		= 0x2,
	DCB_OUTPUT_LVDS		= 0x3,
	DCB_OUTPUT_DP		= 0x4,
	DCB_OUTPUT_EOL		= 0xe,
	DCB_OUTPUT_UNUSED	= 0xf,
};

u16 dcb_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *ent, u8 *len);
u16 dcb_outp(struct nouveau_bios *, u8 idx, u8 *ver, u8 *len);
int dcb_outp_foreach(struct nouveau_bios *, void *data, int (*exec)
		     (struct nouveau_bios *, void *, int index, u16 entry));

#endif
+26 −0
Original line number Diff line number Diff line
#ifndef __NVBIOS_GPIO_H__
#define __NVBIOS_GPIO_H__

struct nouveau_bios;

enum dcb_gpio_func_name {
	DCB_GPIO_PANEL_POWER = 0x01,
	DCB_GPIO_TVDAC0 = 0x0c,
	DCB_GPIO_TVDAC1 = 0x2d,
	DCB_GPIO_PWM_FAN = 0x09,
	DCB_GPIO_FAN_SENSE = 0x3d,
	DCB_GPIO_UNUSED = 0xff
};

struct dcb_gpio_func {
	u8 func;
	u8 line;
	u8 log[2];
};

u16 dcb_gpio_table(struct nouveau_bios *);
u16 dcb_gpio_entry(struct nouveau_bios *, int idx, int ent, u8 *ver);
int dcb_gpio_parse(struct nouveau_bios *, int idx, u8 func, u8 line,
		   struct dcb_gpio_func *);

#endif
+53 −60
Original line number Diff line number Diff line
/*
 * Copyright 2011 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef __NOUVEAU_GPIO_H__
#define __NOUVEAU_GPIO_H__

struct gpio_func {
	u8 func;
	u8 line;
	u8 log[2];
};
#include <core/subdev.h>
#include <core/device.h>

#include <subdev/bios.h>
#include <subdev/bios/gpio.h>

struct nouveau_gpio {
	struct nouveau_subdev base;

	/* hardware interfaces */
	void (*reset)(struct nouveau_gpio *);
	int  (*drive)(struct nouveau_gpio *, int line, int dir, int out);
	int  (*sense)(struct nouveau_gpio *, int line);
	void (*irq_enable)(struct nouveau_gpio *, int line, bool);

	/* software interfaces */
	int  (*find)(struct nouveau_gpio *, int idx, u8 tag, u8 line,
		     struct dcb_gpio_func *);
	int  (*set)(struct nouveau_gpio *, int idx, u8 tag, u8 line, int state);
	int  (*get)(struct nouveau_gpio *, int idx, u8 tag, u8 line);
	int  (*irq)(struct nouveau_gpio *, int idx, u8 tag, u8 line, bool on);

	/* interrupt handling */
	struct list_head isr;
	spinlock_t lock;

/* nouveau_gpio.c */
int  nouveau_gpio_create(struct drm_device *);
void nouveau_gpio_destroy(struct drm_device *);
int  nouveau_gpio_init(struct drm_device *);
void nouveau_gpio_fini(struct drm_device *);
void nouveau_gpio_reset(struct drm_device *);
int  nouveau_gpio_drive(struct drm_device *, int idx, int line,
			int dir, int out);
int  nouveau_gpio_sense(struct drm_device *, int idx, int line);
int  nouveau_gpio_find(struct drm_device *, int idx, u8 tag, u8 line,
		       struct gpio_func *);
int  nouveau_gpio_set(struct drm_device *, int idx, u8 tag, u8 line, int state);
int  nouveau_gpio_get(struct drm_device *, int idx, u8 tag, u8 line);
int  nouveau_gpio_irq(struct drm_device *, int idx, u8 tag, u8 line, bool on);
void nouveau_gpio_isr(struct drm_device *, int idx, u32 mask);
int  nouveau_gpio_isr_add(struct drm_device *, int idx, u8 tag, u8 line,
	void (*isr_run)(struct nouveau_gpio *, int idx, u32 mask);
	int  (*isr_add)(struct nouveau_gpio *, int idx, u8 tag, u8 line,
			void (*)(void *, int state), void *data);
void nouveau_gpio_isr_del(struct drm_device *, int idx, u8 tag, u8 line,
	void (*isr_del)(struct nouveau_gpio *, int idx, u8 tag, u8 line,
			void (*)(void *, int state), void *data);
};

static inline bool
nouveau_gpio_func_valid(struct drm_device *dev, u8 tag)
static inline struct nouveau_gpio *
nouveau_gpio(void *obj)
{
	struct gpio_func func;
	return (nouveau_gpio_find(dev, 0, tag, 0xff, &func)) == 0;
	return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_GPIO];
}

static inline int
nouveau_gpio_func_set(struct drm_device *dev, u8 tag, int state)
{
	return nouveau_gpio_set(dev, 0, tag, 0xff, state);
}
#define nouveau_gpio_create(p,e,o,d)                                           \
	nouveau_gpio_create_((p), (e), (o), sizeof(**d), (void **)d)
#define nouveau_gpio_destroy(p)                                                \
	nouveau_subdev_destroy(&(p)->base)
#define nouveau_gpio_fini(p,s)                                                 \
	nouveau_subdev_fini(&(p)->base, (s))

static inline int
nouveau_gpio_func_get(struct drm_device *dev, u8 tag)
{
	return nouveau_gpio_get(dev, 0, tag, 0xff);
}
int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *,
			 struct nouveau_oclass *, int, void **);
int nouveau_gpio_init(struct nouveau_gpio *);

extern struct nouveau_oclass nv10_gpio_oclass;
extern struct nouveau_oclass nv50_gpio_oclass;
extern struct nouveau_oclass nvd0_gpio_oclass;

void nv50_gpio_dtor(struct nouveau_object *);
int  nv50_gpio_init(struct nouveau_object *);
int  nv50_gpio_fini(struct nouveau_object *, bool);
void nv50_gpio_intr(struct nouveau_subdev *);
void nv50_gpio_irq_enable(struct nouveau_gpio *, int line, bool);

#endif
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/io-mapping.h>
#include <linux/vmalloc.h>
#include <linux/acpi.h>
#include <linux/dmi.h>

#include <asm/unaligned.h>

Loading